use*_*615 11 java spring hibernate
我有一个问题,因为Hibernate 4.1.8导致以下异常:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2]
Run Code Online (Sandbox Code Playgroud)
我在两个实体之间有一个简单的OneToMany关联:
@Entity(name = "Ppv")
@Table(name = "PPV")
public static class Ppv {
@Id
Long ppvId;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "ppv")
Set<Uvazek> uvazeks = new HashSet<Uvazek>(0);
}
@Entity(name = "Uvazek")
@Table(name = "UVAZEK")
public static class Uvazek {
@Id
Long uvazekId;
@ManyToOne
@JoinColumn(name = "PPV_FXID")
Ppv ppv;
}
Run Code Online (Sandbox Code Playgroud)
和一个测试案例,我有一个Ppv和两个Uvazek.当我加载和分离Ppv时,删除一个与加载的Ppv相关联的Uvazek并合并Ppv我得到一个异常.
jdbcTemplate.execute("insert into PPV values(1)");
jdbcTemplate.execute("insert into UVAZEK values(2, 1)");
jdbcTemplate.execute("insert into UVAZEK values(3, 1)");
Ppv ppv = (Ppv) getSession().get(Ppv.class, 1l);
getSession().clear();
getSession().delete(getSession().get(Uvazek.class, 2l));
getSession().flush();
getSession().merge(ppv);
getSession().flush(); //Causes the exception
Run Code Online (Sandbox Code Playgroud)
在Ppv合并期间,Hibernate尝试加载已删除的Uvazek.即使Uvazek被删除,Hibernate仍然有关于它的信息
org.hibernate.collection.internal.AbstractPersistentCollection.storedSnapshot
Run Code Online (Sandbox Code Playgroud)
在uvazek的独立Ppv上.在以前的版本(<4.1.8)中,这可行.在这个简单的例子中,我可以通过添加orphanRemoval=true在Ppv上设置的uvazeks 来修复它,而不是删除uvazek从在Ppv上设置的uvazeks中删除它.
所以我的问题是:这是一个Hibernate错误还是我的不良做法?
Ang*_*ity 11
问题是尝试合并id = 2的Uvazek.Hibernate看到它有一个密钥,但它不知道对象是否是脏的,所以不清楚是否应该进行SQL更新.
但由于密钥为2,Hibernate知道对象必须存在于数据库中,因此它会尝试加载对象,以便将其与刚才在内存中接收的版本进行比较,以查看对象是否有一些待处理的修改.被同步到数据库.
但是select没有返回结果,所以Hibernate有相互矛盾的信息:一方面数据库说对象不存在.另一方面,内存中的对象表示对象必须与键2一起存在.无法确定哪个是正确的,因此ObjectNotFoundException抛出.
发生的事情是,在此版本之前,代码意外地基于同时修复的错误,因此这不再有效.
最佳做法是避免清除并仅在需要作为内存优化时使用它,通过仅清除您知道在同一会话中不会被修改或需要的对象,看看Is Session clear()被认为是有害的.
| 归档时间: |
|
| 查看次数: |
23400 次 |
| 最近记录: |