2017-02-07 14 views
0

Я пытаюсь сохранить 3 сущности с отношениями «один ко многим», но я не могу понять это правильно. Это то, что у меня есть:JPA однонаправленное отношение «один ко многим» сохраняется

@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 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 не может быть пустым.

Отношение однонаправленное, поэтому я не добавил сторону ManyToOne.

Для того, чтобы ответить на некоторые комментарии:

  1. Я использую JPA только
  2. соотношение выглядит следующим образом:

    Человек может иметь несколько телефонных.

    Телефон имеет составной первичный ключ:

    - 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 
); 
+0

Вы используете Hibernate и JPA или только JPA? – Gatusko

+0

Как вы представляете, как personId и brandCode устанавливаются в телефоне? С точки зрения моделирования не являются люди <-> телефонов во многих отношениях и телефон должен иметь бренд ?? –

+0

Как я уже отмечал в своем предыдущем комментарии, ваш код в корне ошибочен. Два поля ID в телефоне не могут быть установлены волшебным образом. Кроме того, я не понимаю вашу модель или схему вашей базы данных. –

ответ

0

Набор @GeneratedValue(strategy = GenerationType.AUTO) для Primary ключи от Mobil e и Phone.

+0

Спасибо за ваш ответ, но он не работает – user1341300

+0

Можете ли вы поделиться запросами sql для этих трех таблиц, будет легко для меня отлаживать. @ user1341300 – zillani

+0

Я добавил sql для генерации таблиц – user1341300

0

Вы используете человек идентификатор в качестве идентификатора в классе Телефон

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

место другого столбца, как 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); 
+0

Это означает, что я должен сначала перенести Person, а затем снова вызвать em – user1341300

Смежные вопросы