javax.persistence.EntityNotFoundException: 无法找到 ID 为 X 的对象
javax.persistence.EntityNotFoundException: Unable to find object with id X
我正在尝试保留一个对象,之后我想向该对象添加 2 个列表,然后更新它(因为我无法将对象与列表一起保留)。
所有都在一个循环内完成,第一次迭代工作正常,从第二次我得到一个 EntityNotFoundException
说找不到 ID 来进行更新。
private Foo foo;
private FooDao dao;
for(int i = 0 ; i<10 ; i++){
foo = new Foo();
foo.setVar(i);
dao.save(foo);
generateLists(); //creates a new list every interaction
foo.setCatList(catList);
foo.setBarList(barList);
dao.update(foo);
}
如果我删除列表和更新它工作正常。
对象:
@Entity
public class Foo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Integer id;
@Basic(optional = false)
@NotNull
private String var;
@OneToMany(cascade = CascadeType.ALL)
private List<Bar> barList;
@OneToMany(cascade = CascadeType.ALL)
private List<Cat> catList;
//Getters and Setters
}
DAO 方法:
public void save(Foo foo) {
this.manager.joinTransaction();
this.manager.persist(foo);
//this.manager.flush(); Tried this, but didn't work
}
public void update(Foo foo) {
this.manager.joinTransaction();
this.manager.merge(foo);
}
错误:
ERROR [org.jboss.as.ejb3] (EJB default - 1) javax.ejb.EJBTransactionRolledbackException: Unable to find foo with id 4
ERROR [org.jboss.as.ejb3.invocation] (EJB default - 1) JBAS014134: EJB Invocation failed on component FooDao for method public void FooDao.atualiza(Foo): javax.ejb.EJBTransactionRolledbackException: Unable to find Foo with id 4
ps:使用这种通用方法来简化,如果需要,我将post我的解决方案(或我称之为解决方案的混乱)
因为您要再次添加相同的列表,并且 again.Since 您有 OneToMany,第二个事务表示您已经保留了该列表。
解决方法是更改与 ManyToMany 的关系
我认为问题出在事务获取事务并在 dAO 的保存方法中提交。
this.manager.getTransaction().commit();
如果出现错误,那是因为没有活动事务,这就是刷新失败的原因。确保您在事务中,考虑使用 EntityTransaction
围绕您的 DAO 方法开始、提交和结束事务。
如果您没有活动的 TX,您将无法将实体写入数据库,并且当您尝试合并某些内容时,实体将找不到,这就是您的原因得到 EntityNotFoundException
--- 更新
进行合并时,Foo 对象的 ID 是什么?我相信这不是正确的,或者至少是数据库中插入的最后一个 ID,所以我的建议是先查找然后合并。
使用
<T> T find(java.lang.Class<T> entityClass,
java.lang.Object primaryKey)
使用 id,并验证实例具有正确的密钥
将@NotFound(action = NotFoundAction.IGNORE) 添加到@ManyToOne 或@OneToOne 是有帮助的,因为..ToOne 默认是FetchType.EAGER
我遇到了类似的问题。通过将 @ManyToOne
注释更新为:
来修复
@NotNull
@JoinColumn(nullable = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private ParentEntityClass parent;
添加:nullable = false
、optional = false, fetch = FetchType.LAZY
以及,除此之外 - @NotNull
(javax.validation.constraints.NotNull - 可能没有必要, 只是为了防止 null-ables :) )
我正在尝试保留一个对象,之后我想向该对象添加 2 个列表,然后更新它(因为我无法将对象与列表一起保留)。
所有都在一个循环内完成,第一次迭代工作正常,从第二次我得到一个 EntityNotFoundException
说找不到 ID 来进行更新。
private Foo foo;
private FooDao dao;
for(int i = 0 ; i<10 ; i++){
foo = new Foo();
foo.setVar(i);
dao.save(foo);
generateLists(); //creates a new list every interaction
foo.setCatList(catList);
foo.setBarList(barList);
dao.update(foo);
}
如果我删除列表和更新它工作正常。
对象:
@Entity
public class Foo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Integer id;
@Basic(optional = false)
@NotNull
private String var;
@OneToMany(cascade = CascadeType.ALL)
private List<Bar> barList;
@OneToMany(cascade = CascadeType.ALL)
private List<Cat> catList;
//Getters and Setters
}
DAO 方法:
public void save(Foo foo) {
this.manager.joinTransaction();
this.manager.persist(foo);
//this.manager.flush(); Tried this, but didn't work
}
public void update(Foo foo) {
this.manager.joinTransaction();
this.manager.merge(foo);
}
错误:
ERROR [org.jboss.as.ejb3] (EJB default - 1) javax.ejb.EJBTransactionRolledbackException: Unable to find foo with id 4
ERROR [org.jboss.as.ejb3.invocation] (EJB default - 1) JBAS014134: EJB Invocation failed on component FooDao for method public void FooDao.atualiza(Foo): javax.ejb.EJBTransactionRolledbackException: Unable to find Foo with id 4
ps:使用这种通用方法来简化,如果需要,我将post我的解决方案(或我称之为解决方案的混乱)
因为您要再次添加相同的列表,并且 again.Since 您有 OneToMany,第二个事务表示您已经保留了该列表。
解决方法是更改与 ManyToMany 的关系
我认为问题出在事务获取事务并在 dAO 的保存方法中提交。
this.manager.getTransaction().commit();
如果出现错误,那是因为没有活动事务,这就是刷新失败的原因。确保您在事务中,考虑使用 EntityTransaction
围绕您的 DAO 方法开始、提交和结束事务。
如果您没有活动的 TX,您将无法将实体写入数据库,并且当您尝试合并某些内容时,实体将找不到,这就是您的原因得到 EntityNotFoundException
--- 更新
进行合并时,Foo 对象的 ID 是什么?我相信这不是正确的,或者至少是数据库中插入的最后一个 ID,所以我的建议是先查找然后合并。
使用
<T> T find(java.lang.Class<T> entityClass,
java.lang.Object primaryKey)
使用 id,并验证实例具有正确的密钥
将@NotFound(action = NotFoundAction.IGNORE) 添加到@ManyToOne 或@OneToOne 是有帮助的,因为..ToOne 默认是FetchType.EAGER
我遇到了类似的问题。通过将 @ManyToOne
注释更新为:
@NotNull
@JoinColumn(nullable = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private ParentEntityClass parent;
添加:nullable = false
、optional = false, fetch = FetchType.LAZY
以及,除此之外 - @NotNull
(javax.validation.constraints.NotNull - 可能没有必要, 只是为了防止 null-ables :) )