Hibernate session.clear()分离引用实体并创建新记录

Hibernate 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

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_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映射。如果您希望有多个项具有相同的父项,则必须使用多个父项映射。

One
Item
只能有一个父项
Item
。如何映射自我
实体的
manytone
关系。如果我们有另一个
实体
子实体,那么我们可以将其映射到
多个实体
也许我认为这是错误的,但是如果您有两个不同的项目与同一个父实体,那么您需要多个实体关系,而不管是自引用还是对另一个实体的引用。