Java JPA冬眠。在一次调用中将具有外键引用的父实体和子实体持久化到父实体

Java JPA冬眠。在一次调用中将具有外键引用的父实体和子实体持久化到父实体,java,hibernate,jpa,Java,Hibernate,Jpa,我有以下问题:a班 Class A { ... @Id @GeneratedValue( strategy = GenerationType.IDENTITY ) @JsonIgnore private Long id; @OneToMany(cascade=CascadeType.PERSIST, orphanRemoval = true, fetch = FetchType.EAGER) @JsonVi

我有以下问题:a班

 Class A {
      ...

      @Id
      @GeneratedValue( strategy = GenerationType.IDENTITY )
      @JsonIgnore
      private Long id;

      @OneToMany(cascade=CascadeType.PERSIST, orphanRemoval = true, fetch = FetchType.EAGER)
      @JsonView(View.Extended.class )
      @JoinColumn(name="b_fkey", referencedColumnName = "id")
      List<B> b;
      ...
 }
我试图坚持如下:

 ...
 A a = new A();
 a.setStuff();
 A aa = aDao.save(a);
 // no list of B's

 for(B b : List<B>) {
     b.setB_fkey(aa.getId());
     bDao.persist(b);
 }
 ...
。。。
A=新的A();
a、 设置凝灰岩();
A aa=自动保存(A);
//没有B的列表
对于(B:列表){
b、 setB_fkey(aa.getId());
bDao.b;
}
...
这非常有效,但我希望它以以下X方式保存:

 ...
 A a = new A();
 a.setStuff();
 a.setB(List<B>)
 aDao.persist(a);
 ...
。。。
A=新的A();
a、 设置凝灰岩();
a、 挫折(名单)
aDao.persist(a);
...
现在它抛出一个错误“列'f_key'不能为null”,因为f_key是一个外键,它引用的是尚未生成的a.id值


问题:如何以“X方式”保存它?

您可以尝试下面的代码吗:

    Class A {
      ...

      @JsonIgnore
      private Long id; @Id
      @GeneratedValue( strategy = GenerationType.IDENTITY )
      public Long getId()
      {
          return id;
      }

      public void setId(Long id)
      {
          this.id = id;
      }

      @JsonView(View.Extended.class )
      List<B> b;

      @OneToMany(cascade=CascadeType.PERSIST, orphanRemoval = true, fetch = FetchType.EAGER)
      @JoinColumn(name="b_fkey")
      public List<B> getB(List<B> bList){
          return b;
      }      

      public void setB(List<B> bList){
          this.b = bList;
      }
A类{
...
@杰索尼奥雷
私有长id;@id
@GeneratedValue(策略=GenerationType.IDENTITY)
公共长getId()
{
返回id;
}
公共无效集合id(长id)
{
this.id=id;
}
@JsonView(View.Extended.class)
名单b;
@OneToMany(cascade=CascadeType.PERSIST,orphanRemoving=true,fetch=FetchType.EAGER)
@JoinColumn(name=“bfkey”)
公共列表getB(列表bList){
返回b;
}      
公共无效挫折(列表bList){
这个.b=bList;
}

getter和setter上的注释使您能够更好地控制hibernate列。

我认为您有两个问题:

首先,您正在映射一个双向关系,但只是“半心半意”,即,您没有将a映射到B,只映射到它的ID

更好的地图,如:

Class B {

  @ManyToOne(...)
  private A a;
}
其次,如果要在Hibernate中映射双向关系,则必须设置两侧(请参阅)

这主要通过以下方法实现:

Class A {
   void setB(List<B> bs) {
     this.bs = bs;
     for (B b: bs) {
         b.setA(this);
     }
   }
}
A类{
无效收进(列表bs){
这个.bs=bs;
(B:bs){
b、 刚毛(本);
}
}
}

如果你不需要B中的A,你也可以使用单向映射。

我不需要B中的A。这是正确的,所以我不需要在类B中定义多个。我只需要A中的一个域,也可以在公共的void setB(List B_List){//(B:B_List)B.setF_键的无方向映射(this.getId());this.B=B;}这将不起作用,因为当调用函数时,函数中的id仍然为null。正如您所描述的,它无法知道其f_键应该是A的id,因此无法设置它。如果您将A映射为B中的实体,并使用正确的级联,则Hibernate将在持久化时检索A的id,并在B中正确设置它。或者,您可以放置一个@PrePersist注释的方法在循环中通过B并在那里设置它们的fkey,但在您的情况下,这不是“正确的”操作。
Class A {
   void setB(List<B> bs) {
     this.bs = bs;
     for (B b: bs) {
         b.setA(this);
     }
   }
}