提问者:小点点

JPA单向一对多关系持续存在


我试图坚持3个具有一对多关系的实体,但我做不到。这就是我所拥有的:

@Entity
@Table(name = "tb_person")
public class Person {
    @Id
    @SequenceGenerator(name = "my_seq", sequenceName = "pk_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
    @Column(name="person_id")
    private long personId;

    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "person_id", referencedColumnName = "person_id")
    private List<Phone> phones;
}


@Entity
@IdClass(PersonBrandId.class)
@Table(name = "tb_person_phone")
public class Phone {
     @Id
     @Column(name = "retailer_id")
     private long personId;

     @Id
     @Column(name = "brand_code")
     private String brandCode;

     @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
     @JoinColumns({
        @JoinColumn(name = "brand_code", referencedColumnName = "brand_code", insertable = false, updatable = false),
        @JoinColumn(name = "person_id", referencedColumnName = "person_id", insertable = false, updatable = false)})
     List<Mobile> mobiles;

     ...other fields...
}

@Entity
@Table(name = "tb_mobile")
public class Mobile {
    @Id
    @SequenceGenerator(name = "my_seq2", sequenceName = "pk_seq2", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq2")
    @Column(name="mobile_id")
    private long mobileId;

    @Column(name = "person_id")
    private long personId;

    ...other fields...
}

所以,我想达到的是坚持人只,因为级联,电话和手机将自动坚持。示例:

Person person = new Person();
Phone phone = new Phone();
Mobile mobile = new Mobile();
phone.getMobiles().add(mobile);
person.getPhones().add(phone);

em.persist(person);

问题是我收到一个错误,说 tb_person_phone.person_id 不能为空。

这种关系是单向的,所以我没有添加多对一方。

为了回答一些评论:

>

  • 我只使用JPA
  • 关系如下:

    手机有复合主键:

       - person_id in Person
    
       - brand_code in Brand (a table with a list of brands)
    

    Mobile具有主键:Mobile_id

      has two FK:
    
       - person_id and brand_code both referencing the table Phone 
    

    SQL生成表格:

    CREATE TABLE "TB_PERSON"
    (   "PERSON_ID" NUMBER NOT NULL ENABLE, 
    "PERSON_NAME" VARCHAR2(100 BYTE) NOT NULL ENABLE, 
     CONSTRAINT "PERSON_PK" PRIMARY KEY ("PERSON_ID")
    );
    
    
    CREATE TABLE "TB_PERSON_PHONE" 
    (   "PERSON_ID" NUMBER NOT NULL ENABLE, 
        "BRAND_CODE" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
        "ATTR1" VARCHAR2(1 BYTE), 
        "ATTR2" VARCHAR2(100 BYTE), 
     CONSTRAINT "PERSON_PHONE_PK" PRIMARY KEY ("PERSON_ID", "BRAND_CODE")
     FOREIGN KEY ("PERSON_ID")
      REFERENCES "TB_PERSON" ("PERSON_ID") ENABLE, 
     FOREIGN KEY ("BRAND_CODE")
      REFERENCES "TB_BRAND" ("BRAND_CODE") ENABLE
    );
    
    
    CREATE TABLE "TB_MOBILE" 
    (   "MOBILE_ID" NUMBER NOT NULL ENABLE, 
    "PERSON_ID" NUMBER NOT NULL ENABLE, 
    "BRAND_CODE" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
    "NUMBER" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
    "ATTR1" VARCHAR2(100 BYTE), 
    "ATTR2" VARCHAR2(100 BYTE), 
     CONSTRAINT "MOBILE_PK" PRIMARY KEY ("MOBILE_ID"),
     CONSTRAINT "MOBILE_UQ" UNIQUE ("NUMBER", "PERSON_ID", "BRAND_CODE")
     USING INDEX (CREATE UNIQUE INDEX "MOBILE_UQ_IDX" ON "TB_MOBILE" ("NUMBER",       "PERSON_ID", "BRAND_CODE"),
     FOREIGN KEY ("PERSON_ID", "BRAND_CODE")
      REFERENCES "TB_PERSON_PHONE" ("PERSON_ID", "BRAND_CODE") ENABLE
     );
    

  • 共2个答案

    匿名用户

    为移动和电话实体的主键设置 @GeneratedValue(策略 = 生成类型.AUTO)。

    匿名用户

    您正在使用个人id作为Phone类中的标识符

    @Id
     @Column(name = "retailer_id")
     private long personId;
    

    将另一列作为Id,并添加一些生成Id策略或

     Person person = new Person();
    
     em.persist(person); //<
    
     Phone phone = new Phone();
     Mobile mobile = new Mobile();
     phone.getMobiles().add(mobile);
     person.getPhones().add(phone);
    
     phone.setPersonId(person.getId()); // <
    
     em.persist(person);