gpt4 book ai didi

java - JPA:orphanRemoval=true 删除时有时会抛出 NullPointerException

转载 作者:行者123 更新时间:2023-11-30 03:46:59 25 4
gpt4 key购买 nike

我正在使用 JPA 2.1、EclipseLink 2.5.0、SQLite3 数据库和 Swing 制作一个应用程序。

我有两个实体,EntityClientEntityPhone ,其中第一个有 OneToMany与第二个的关系。两个实体都有自己的主键,它们的关系由 JoinTable 表示。 。为了访问和保留所有数据,我使用通用 DAO .

我试图级联删除,所以如果删除客户端,他的手机也会被删除。我已经通过添加 orphanRemoval=true 实现了这一点和cascade={CascadeType.ALL}OneToMany注释和 CascadeOnDelete注解。

问题是,由于 orphanRemoval=true ,如果我插入一个新客户端,然后尝试删除它,我将得到 NullPointerException 。但如果我关闭应用程序并再次启动它,它会让我毫无问题地删除客户端。

这些是实体:

@Entity
@Table(name="clientes")
public class EntityClient {

@Id
@Column(name="id_cliente")
private Integer idClient;

@Column(name="nombre")
private String name;

@Column(name="apellidos")
private String surname;

@OneToMany(mappedBy="client",
targetEntity=EntityPhone.class,
fetch=FetchType.EAGER,
orphanRemoval=true,
cascade={CascadeType.ALL})
@CascadeOnDelete
private ArrayList<EntityPhone> phones;

//The rest of the fields and the getters and setters...
}
@Entity
@Table(name="telefonos")
public class EntityPhone {

@Id
@Column(name="id_telefono")
private Integer idPhone;

@Column(name="telefono")
private String phone;

@Column(name="descripcion")
private String description;

@ManyToOne(fetch=FetchType.EAGER)
@JoinTable(name="clientes_telefonos",
joinColumns=@JoinColumn(name="id_telefono",
referencedColumnName="id_telefono"),
inverseJoinColumns=@JoinColumn(name="id_cliente",
referencedColumnName="id_cliente"))
private EntityClient client;

//Getters and setters...
}

这是通用的DAO显然有一个删除方法:

public abstract class DAO<Entity, ID extends Serializable> {

private Class<Entity> entityClass;

private final static EntityManagerFactory emf = Persistence.createEntityManagerFactory("Database_Name");
private final static EntityManager em = emf.createEntityManager();


public void delete(ID id) throws PersistenceException {

em.getTransaction().begin();

Entity row = em.find(entityClass, id);

em.remove(row);

em.getTransaction().commit();
}

//...
}

这是我遇到的异常:

javax.persistence.RollbackException: java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
at model.dao.DAO.delete(DAO.java:127)
at controller.delete.ControllerDeleteClient.actionPerformed(ControllerDeleteClient.java:39)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.internal.queries.CollectionContainerPolicy.iteratorFor(CollectionContainerPolicy.java:150)
at org.eclipse.persistence.mappings.CollectionMapping.recordPrivateOwnedRemovals(CollectionMapping.java:1724)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.recordPrivateOwnedRemovals(ObjectBuilder.java:3445)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:687)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1514)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1167)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
... 38 more

最佳答案

您正在使用静态来保存您的EntityManager,这是一个坏主意 - 它不是线程安全的。您需要为每个上下文获取一个新的:

public void delete(ID id) throws PersistenceException {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Entity row = em.find(entityClass, id);
em.remove(row);
em.getTransaction().commit();
}

这也可能有助于解决您当前的问题,该问题似乎是由于陈旧的缓存造成的。一些如何使用空电话集合管理您要删除的 EntityClient 实例。您可以提交一个错误,让 EclipseLink 处理 null 集合,但它实际上不应该为 null。由于此 EntityManager 是长期存在的(在类上是静态的),因此您必须跟踪如何管理和创建此实体,并且该集合与引用它的 EntityPhone.client 关系保持同步。重新启动应用程序会清除缓存,因此查找操作将构建 EntityClient 的新实例,并正确填充集合,从而避免 NPE。您可以通过调用 em.refresh(entityClass) 获得相同的效果,但跟踪集合如何为 null 可能会给您带来更好的性能。

关于java - JPA:orphanRemoval=true 删除时有时会抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25392946/

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