简体   繁体   English

JPA:了解OneToOne双向关系

[英]JPA: Understanding the OneToOne bidirectional relationship

I 'm trying to understand the possible way to use this relationship from the inverse side. 我试图理解从反面使用这种关系的可能方式。

My entities: 我的实体:

@Entity
public class Person {
    @Id @GeneratedValue
    private Long id;
    private String name;

    @OneToOne
    private Dossier dossier;

    //----------------------------------------
    // getters/setters/constructors
}

@Entity
public class Dossier {
    @Id @GeneratedValue
    private Long id;
    private String dossierInfo;

    @OneToOne(mappedBy = "dossier", fetch = FetchType.EAGER)
    private Person person;

    //----------------------------------------
    // getters/setters/constructors
}

And the main method snippet: 主要方法片段:

tx.begin();
{
    // persist
    Dossier d = new Dossier("some info");
    d.setId(1000l);
    em.persist(d);
    em.persist(new Person("Peter", d));

    // find
    Dossier dossier = em.find(Dossier.class, 1000l);
    System.err.println(dossier.getDossierInfo());
    System.err.println(dossier.getPerson().getName());   // <<  NullPointer exception
}
tx.commit();

So, how can we get the Person object from Dossier one? 那么,我们如何从Dossier获取Person对象呢? Or how should I change my entities to do that? 或者我应该如何更改我的实体呢?

The object d doesn't have a reference of Person, so, if you look the table, the person column is set to null. 对象d没有Person的引用,因此,如果查看表,则person列设置为null。 In a bidirectional one-to-one relationship mapping, both entities, the owner and inverse side should have a reference of the other entity. 在双向一对一关系映射中,两个实体,所有者和反面都应该具有另一个实体的引用。 So, your code should be: 所以,你的代码应该是:

Dossier dossier = new Dossier("some info");
dossier.setId(1000L);
Person person = new Person("Peter", dossier);
dossier.setPerson(person);
em.persist(person);
em.persist(dossier);

Do you have the data correctly inserted in the DB? 您是否已将数据正确插入数据库? Also if you put cascade = Cascade.ALL on the Person mapping you won`t need to persist first Dossier. 此外,如果您在Person映射上放置cascade = Cascade.ALL,您将不再需要保留第一个Dossier。 Try adding it and tell me if it does not work. 尝试添加它并告诉我它是否不起作用。

Seems I found my mistake. 好像我发现了我的错误。 In transaction section, before persisting entities we need to correctly set all links (I forgot to set the person link in dossier object). 在事务部分中,在持久化实体之前,我们需要正确设置所有链接(我忘了在档案对象中设置人员链接)。 So here is the valid code: 所以这是有效的代码:

tx.begin();
{
    // persist
    Dossier d = new Dossier("some info");
    d.setId(1000l);

    Person p = new Person("Peter", d);   // set link to dossier

    d.setPerson(p);                      // set link to person

    em.persist(d);
    em.persist(p);

    // find
    Dossier dossier = em.find(Dossier.class, 1000l);
    System.err.println(dossier.getDossierInfo());
    System.err.println(dossier.getPerson().getName());
}
tx.commit();

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

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