Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA递归一对一延迟加载引用未更新_Java_Hibernate_Jpa - Fatal编程技术网

Java JPA递归一对一延迟加载引用未更新

Java JPA递归一对一延迟加载引用未更新,java,hibernate,jpa,Java,Hibernate,Jpa,使用JPA 2.1和Hibernate 4.3.6.Final,我有以下简单实体: @Entity @Table(name = "CONTACT") public class Contact { @Id @Column(name = "ID") private String id = UUID.randomUUID().toString(); @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PA

使用JPA 2.1和Hibernate 4.3.6.Final,我有以下简单实体:

@Entity
@Table(name = "CONTACT")
public class Contact {
    @Id
    @Column(name = "ID")
    private String id = UUID.randomUUID().toString();

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PARTNER_ID")
    private Contact partner;

    Contact() {
    }

    public void assignPartner(final Contact other) {
        this.partner = Objects.requireNonNull(other);
        other.partner = this;
    }

    public void unassignPartner() {
        if (partner != null) {
            partner.partner = null;
        }

        partner = null;
    }
}
注意延迟加载的一对一递归关联到合作伙伴联系人。还要注意assignPartner和unassignPartner如何管理双向关系

以及以下方法:

private static void assignPartner(final EntityManager entityManager) {
    entityManager.getTransaction().begin();

    final Contact contact1 = entityManager.find(Contact.class, CONTACT1_ID);
    final Contact contact2 = entityManager.find(Contact.class, CONTACT2_ID);

    contact1.assignPartner(contact2);

    entityManager.getTransaction().commit();
}

private static void unassignPartner(final EntityManager entityManager) {
    entityManager.getTransaction().begin();

    final Contact contact1 = entityManager.find(Contact.class, CONTACT1_ID);
    contact1.unassignPartner();

    entityManager.getTransaction().commit();
}
假设CONTACT1\u ID和CONTACT2\u ID的现有行,在运行assignPartner然后unassignPartner之后,数据库状态显示CONTACT1具有空的partner\u ID,CONTACT2仍然具有非空的partner\u ID

但是,如果我将Contact.partner fetch类型更改为EAGER,则在运行assignPartner然后是unassignPartner之后,数据库状态显示contact1和contact2都有空的partner\u id

为什么呢?为什么对合作伙伴实体的更改没有刷新到数据库中

编辑1

也不会传播通过直接字段访问对合作伙伴引用所做的更改,例如partner.firstName=DUMPED。 通过方法访问对合作伙伴引用的更改(例如partner.setFirstNameDUMPED)将被传播。 未传播partner.partner=null或partner.setPartnernull

编辑2

正如Rat2000所建议的,将取消分配逻辑移到Contact.unassignPartner方法外部和unassignpartnertitymanager方法内部似乎可以正常工作。因此,这实际上与Hibernate如何处理contact1.partner代理有关,特别是contact1.partner.partner代理

    final Contact contact1 = entityManager.find(Contact.class, CONTACT1_ID);
    contact1.getPartner().unassignPartner();
    contact1.unassignPartner();
试试这个:

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.UPDATE)
@JoinColumn(name = "PARTNER_ID")
private Contact partner;

谢谢你的建议,我试过了,结果都一样。提交事务会自动刷新EntityManager,因此这应该没有什么区别。此外,对contact1的更改会刷新到数据库中,但对contact2的更改不会刷新到数据库中。这就是我不明白的。我想你把我弄糊涂了。。。因此,当您保存到数据库时,联系人1的更改将在数据库中显示,但如果您从数据库中重新显示对象contact 2,该对象应具有对联系人1的引用,则联系人合作伙伴为空?contact.unassignPartner为当前实例取消分配合作伙伴,但也为被引用的实例合作伙伴取消分配合作伙伴。因此,在调用contact1.unassignPartner并提交事务后,我希望内存和数据库中都有contact1.partner=null和contact2.partner=null。我在内存中观察到contact1.partner=null和contact2.partner=null,但在数据库中观察到contact1.partner=null和contact2.partner=contact1。恐怕结果是一样的。问题不是contact2没有与EntityManager分离,而是它没有更新……让我们来看看。