首页 > 解决方案 > JPA:在父类和子类中都没有使用@IdClass 将外键插入到子类中

问题描述

我有一个复合 PK (id + serial_no) 的父母。孩子也有一个PK(id + serial_no + attribute),其中FK是(id + serial_no)

注意:我使用了@IdClass 而不是@EmbeddedId,因为在我的级中,我有要从序列生成的id(我在stackoverflow 上读到sequencegenerator 不适用于embeddedid)。

问题 :

Caused by: oracle.jdbc.OracleDatabaseException: ORA-01400: cannot insert NULL into ("schema_name"."child"."id")

下面是我的保存逻辑

Parent parent = new Parent();
parent.setSerialNo(0L);
//Note I don't want to set the Id as its supposed to be generated by the sequence

Child child = new Child();
child.setAttribute("abc");
//so in the below line am setting parent in child class
child.setParent(parent);
//note in the child am not setting the id and serial_no coz i want it to come from parent

repository.save(parent);
// I am expecting the cascade so that both the parent and child get saved

以下是我的实体代码:

@Entity
@Table(name = "parent")
@IdClass(ParentPK.class)
public class Parent implements Serializable {
     @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator", sequenceName="o_seq", allocationSize=1)
    private Long id;
    
    @Id
    @Column(name="serial_no")
    Long serialNo; 

     @JsonManagedReference
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private List<Child> childs;
}

@Entity
@Table(name="child")
@IdClass(ChildPK.class)
public class Child implements Serializable{

    @Id
    @Column(name="id")
    Long id;
    
    @Id
    @Column(name="serial_no")
    Long serialNo;
    
    @Id
    @Column(name="attribute")
    String attribute;

    @JoinColumns(value = {
            @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false),
            @JoinColumn(name = "serial_no", referencedColumnName = "serial_no", insertable = false, updatable = false)
        })
    @JsonBackReference
    @ManyToOne(fetch=FetchType.LAZY, optional=true)
    private Parent parent;
}

提前谢谢了

标签: javaspring-boothibernatejpaspring-data-jpa

解决方案


@Entity
@Table(name="child")
@IdClass(ChildPK.class)
public class Child implements Serializable{
  
    @Id
    @Column(name="attribute")
    String attribute;

    @Id
    @JoinColumns(value = {
            @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false),
            @JoinColumn(name = "serial_no", referencedColumnName = "serial_no", insertable = false, updatable = false)
        })
    @JsonBackReference
    @ManyToOne(fetch=FetchType.LAZY, optional=true)
    private Parent parent;
}

class ChildPK implements Serializable {

  Parent parent;
  String attribute;
  ...
}

有关更多详细信息,请参阅有关复合标识符的 Hibernate ORM 文档。


推荐阅读