简体   繁体   English

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

[英]JPA recursive one-to-one lazy-loaded reference not updated

Using JPA 2.1 and Hibernate 4.3.6.Final, I have the following simple entity: 使用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;
    }
}

Notice the lazy-loaded one-to-one recursive association to a partner Contact. 请注意与伙伴联系人的延迟加载的一对一递归关联。 Also notice how assignPartner() and unassignPartner() manage the bi-directional relationship. 另请注意,assignPartner()和unassignPartner()如何管理双向关系。

And the following methods: 以及以下方法:

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();
}

Assuming existing rows for CONTACT1_ID and CONTACT2_ID, after running assignPartner() then unassignPartner(), database state shows that contact1 has a null partner_id and contact2 still has a non-null partner_id. 假设已存在CONTACT1_ID和CONTACT2_ID的行,则在运行assignPartner()然后运行unassignPartner()之后,数据库状态显示contact1的合作伙伴ID为空,contact2的合作伙伴ID为非空。

However, if I change the Contact.partner fetch type to EAGER, after running assignPartner() then unassignPartner(), database state shows that both contact1 and contact2 have null partner_id. 但是,如果我将Contact.partner的访存类型更改为EAGER,则在运行assignPartner()之后再取消unassignPartner()之后,数据库状态将显示contact1和contact2的伙伴名称都为空。

Why is that? 这是为什么? Why are changes to the partner entity not flushed to the database? 为什么对伙伴实体的更改未刷新到数据库?

EDIT 1 编辑1

Changes to the partner reference through direct field access, eg partner.firstName = "DUMPED", are not propagated either. 通过直接字段访问对伙伴引用所做的更改(例如,partner.firstName =“ DUMPED”)也不会传播。 Changes to the partner reference through method access, eg partner.setFirstName("DUMPED"), are propagated. 传播通过方法访问对伙伴引用所做的更改,例如partner.setFirstName(“ DUMPED”)。 Neither partner.partner = null or partner.setPartner(null) are propagated. 不传播partner.partner = null或partner.setPartner(null)。

EDIT 2 编辑2

As suggested by Rat2000, moving the unassignment logic outside the Contact.unassignPartner() method and inside the unassignPartner(EntityManager) method seems to work properly. 正如Rat2000所建议的,将取消分配逻辑移到Contact.unassignPartner()方法之外和unassignPartner(EntityManager)方法内部似乎可以正常工作。 So it's really something to do with how Hibernate deals with the contact1.partner proxy, and in particular the contact1.partner.partner proxy. 因此,这实际上与Hibernate如何处理contact1.partner代理(尤其是contact1.partner.partner代理)有关。

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

Try this: 尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM