简体   繁体   English

JPA OneToOne 双向。

[英]JPA OneToOne bidirectional .

I have two entity classes that are in @OneToOne relation.我有两个实体类在 @OneToOne 关系中。 The example code are as follow:示例代码如下:

public class A {
@Id
private int id;
private String name;
@JoinColumn(name = "B_ID", referencedColumnName = "id")
@OneToOne(cascade=CascadeType.ALL)
private B b;

//setters and getters

}

public class B {
@Id
private int id;
private String name;
@OneToOne(mappedBy="b")
    private A a;
//setter and getters

}

my question here is "Can I use setA(A a) method in class B. I mean like this. .我的问题是“我可以在 class B 中使用 setA(A a) 方法吗?我的意思是这样......

em.getTransaction().begin();
A aa = new A();
aa.setId(1);
aa.setName("JJ");
em.persist(aa);

B bb = new B();
bb.setId(1);
bb.setName("CC");
bb.setA(aa);
em.persist(bb);
em.getTransaction().commit();

When I tried like this, the foreign_key field in table A (B_ID) was saved as null.当我这样尝试时,表A(B_ID)中的foreign_key字段被保存为null。
Please help me.请帮我。

Here , you have specified mappedBy in class B above private A a; 在这里,你已经在private A a;上面的B类中指定了mappedBy private A a; . In a bidirectional relationship , mappedBy means that I am not the owner. 双向关系中, mappedBy意味着我不是所有者。 So It means that A is the owner of the relationship. 所以这意味着A是这段关系的所有者。

In table of A , you will have a foreignkey for table of B. As A is the owner, A is suppose to cascade operations to B. Ideally you should try a.setB() and then persist a. 在A表中,你将有一个B表的外键。由于A是所有者,A假设将操作级联到B.理想情况下你应该尝试a.setB()然后持久化a。

Try below: 试试以下:

em.getTransaction().begin();
//first create B.
B bb = new B();
bb.setId(1);
bb.setName("CC");
em.persist(bb);

//create A with B set in it.
A aa = new A();
aa.setId(1);
aa.setName("JJ");
aa.setB(bb);
em.persist(aa);
em.getTransaction().commit();

Or 要么

em.getTransaction().begin();
//first create B.
B bb = new B();
bb.setId(1);
bb.setName("CC");
// no need to persist bb.

//create A with B set in it.
A aa = new A();
aa.setId(1);
aa.setName("JJ");
aa.setB(bb);
em.persist(aa); // because of cascade all , when you persist A ,
// B will also be persisted.
em.getTransaction().commit();

Use @Cascade({CascadeType.SAVE_UPDATE}) to cascade changes 使用@Cascade({CascadeType.SAVE_UPDATE})级联更改

public class B {
@Id
private int id;
private String name;
@OneToOne(mappedBy="b")
 @Cascade({CascadeType.SAVE_UPDATE}) 
    private A a;
//setter and getters

}

you need to add aa.setB(bb) before em.persist(bb) 你需要在em.persist(bb)之前添加aa.setB(bb)

em.getTransaction().begin();
A aa = new A();
aa.setId(1);
aa.setName("JJ");
em.persist(aa);

B bb = new B();
bb.setId(1);
bb.setName("CC");

aa.setB(bb);//this line should be added
bb.setA(aa);

em.persist(bb);
em.getTransaction().commit();

I had also the same problem.我也有同样的问题。 A class had already Setter Method for class B. My Problem was solved with setter in class B. In Class B i put method setter like this. A class 已经有 class B 的 Setter Method

public void setA(A a){ 
this.a=a;
a.setB(this);
} 

. .

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

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