Hibernate session.clear()分离引用实体并创建新记录
Item.javaHibernate session.clear()分离引用实体并创建新记录,hibernate,session,Hibernate,Session,Item.java @Entity @Table(name = "items") public class Item extends Model { @Id @GeneratedValue @Column(name = "id") private Long id; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(referencedColumnName = "id", name = "parent
@Entity
@Table(name = "items")
public class Item extends Model {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(referencedColumnName = "id", name = "parent_id")
private Item parent;
}
我们正在处理批处理并将其保存到数据库中。在该批中,我们有项
s,其父项如下所示
Item[id=null] {child1}
-> ParentItem[id=null] {parent1}
现在session.save(项目)调用代码>生成以下ID
Item[id=129123] {child1}
-> ParentItem[id=129122] {parent1}
现在session.flush()代码>和会话.clear()代码>已调用
在该批中,我们有另一个项
,该项附加了相同的父项
Item[id=null] {child2}
-> ParentItem[id=null] {parent1 same object attached in child1}
从技术上讲,child2
应该引用在child1
中创建的父项{ParentItem[id=129122]
}。但是当我调用session.save(项目)时
在child2
上创建新的ParentItem
Item[id=129125] {child2}
-> ParentItem[id=129124] {parent1} // I want ParentItem[id=129122] should be here.
注意:这是因为我们调用了session.clear()代码>
我们正在使用以下代码保存记录
IntStream.range(0, items.size())
.filter(i -> items.get(i) != null).forEach(i -> {
T item = items.get(i);
Item it = (Item) item;
session.save(item);
if (i % 50 == 0) {
session.flush();
session.clear();
}
});
tr.commit();
问题:
- 我们应该调用
session.clear()代码>保存所有对象后
- 如果
session.clear()对引用实体调用的代码>比Hibernate无法识别附加到其他对象的对象。[是Hibernate的规则还是缺少一些Hibernate配置]
可能的解决方案:
- 在阅读了几篇文章之后,他们建议使用
无状态会话
李>
你有什么建议
编辑:
我使用了无状态会话#insert
,然后它抛出以下异常。这意味着我们必须显式保存附加的父项(我们不希望这样),那么还有其他方法吗
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.org.openxcell.model.Item
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:294)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:165)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2843)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2818)
at org.hibernate.persister.entity.AbstractEntityPersister$4.bindValues(AbstractEntityPersister.java:3025)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558)
at org.hibernate.internal.StatelessSessionImpl.insert(StatelessSessionImpl.java:141)
at org.hibernate.internal.StatelessSessionImpl.insert(StatelessSessionImpl.java:123)
您正在使用OneTONE映射。如果您希望有多个项具有相同的父项,则必须使用多个父项映射。OneItem
只能有一个父项Item
。如何映射自我实体的manytone
关系。如果我们有另一个实体
子实体,那么我们可以将其映射到多个实体
也许我认为这是错误的,但是如果您有两个不同的项目与同一个父实体,那么您需要多个实体关系,而不管是自引用还是对另一个实体的引用。