gpt4 book ai didi

java - openjpa2.0如何在运行时增强实体?

转载 作者:行者123 更新时间:2023-11-30 09:55:05 25 4
gpt4 key购买 nike

下面是我的测试代码:

package jee.jpa2;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@Test
public class Tester {
EntityManager em;
EntityTransaction tx;
EntityManagerFactory emf;

@BeforeClass
public void setup() {
emf = Persistence.createEntityManagerFactory("basicPU", System.getProperties());
}

@Test
public void insert() {
Item item = new Item();
for (int i = 0; i < 1000; ++i) {
em = emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
item.setId(null);
em.persist(item);
tx.commit();
em.clear();
em.close();
tx=null;
em=null;
}
}

@Test
public void read() {
em = emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
Query findAll = em.createNamedQuery("findAll");
List<Item> all = findAll.getResultList();
for (Item item : all) {
System.out.println(item);
}
tx.commit();
}
}

这是实体:

package jee.jpa2;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;

@Entity
@NamedQuery(name="findAll", query="SELECT i FROM Item i")
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false, updatable= false)
protected Long id;
protected String name;

public Item() {
name = "Digambar";
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return String.format("Item [id=%s, name=%s]", id, name);
}

}

执行测试后出现错误:

Item [id=1, name=Digambar]
Item [id=2, name=Digambar]
PASSED: read
FAILED: insert
<openjpa-2.0.0-r422266:935683 nonfatal store error> org.apache.openjpa.persistence.EntityExistsException: Attempt to persist detached object "jee.jpa2.Item-2". If this is a new instance, make sure any version and/or auto-generated primary key fields are null/default when persisting.
FailedObject: jee.jpa2.Item-2
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2563)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2423)
at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1069)
at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:705)
at jee.jpa2.Tester.insert(Tester.java:33)

请解释这里发生了什么?

最佳答案

为了严格回答问题标题,运行时增强是使用可以在使用 JDK 1.6 时动态加载的 javaagent 完成的(这在 Entity Enhancement 中有记录)。

关于您面临的问题,我怀疑它是一个 OpenJPA 错误(我见过几个类似问题,例如 OPENJPA-755 ),错误消息与您的代码不一致,因为您正在将主键字段设置为 null 并且没有任何版本字段。你应该报告它。

也就是说,“解决”该问题的一种简单方法是在循环内创建一个新的 Item 实例。像这样:

public void insert() {
for (int i = 0; i < 1000; ++i) {
Item item = new Item();
em = emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
em.persist(item);
tx.commit();
em.clear();
em.close();
tx=null;
em=null;
}
}

补充说明:

为什么在创建 EntityManagerFactory 时传递 System.getProperties()

您应该在测试结束时关闭 EntityManagerFactory:

@AfterClass
public static void closeEntityManagerFactory() {
emf.close();
}

更新:回答评论。来自 JPA 规范:

3.2 Entity Instance’s Life Cycle

This section describes the EntityManager operations for managing an entity instance’s lifecycle. An entity instance may be characterized as being new, managed, detached, or removed.

  • A new entity instance has no persistent identity, and is not yet associated with a persistence context.
  • A managed entity instance is an instance with a persistent identity that is currently associated with a persistence context.
  • A detached entity instance is an instance with a persistent identity that is not (or no longer) associated with a persistence context.
  • A removed entity instance is an instance with a persistent identity, associated with a persistence context, that is scheduled for removal from the database.

因此,如果您有一个分离的实体(因此不与持久上下文相关联)并且如果您将带注释的Id 字段设置为null(因此它没有持久身份),那么无论 OpenJPA 行为如何,您都拥有规范定义为新实体的内容。这就是为什么我认为这是 OpenJPA 中的错误(并且错误消息无论如何都是不连贯的)。

关于java - openjpa2.0如何在运行时增强实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3005296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com