0

I am using JPA (Hibernate) and trying to persist entire new entity with childs and composite keys, but when persisting childs i getting null in key. Table structure:

CREATE TABLE IDENTITY_DOCS
(
    PERSON_ID BIGINT NOT NULL,
    DOC_TYPE_ID BIGINT NOT NULL,
    ...
);

CREATE TABLE DOC_TYPES
(
    DOC_TYPE_ID BIGINT PRIMARY KEY NOT NULL,
    ...
);

CREATE TABLE PERSONS
(
    PERSON_ID BIGINT PRIMARY KEY NOT NULL,
    ...
);

Mappings:

@IdClass(...IdentityDocsPK.class)
@Table(name = "IDENTITY_DOCS")
@Entity
public class IdentityDocs {

    @Id
    @Column(name = "PERSON_ID", nullable = false)
    private Long personId;

    @Id
    @Column(name = "DOC_TYPE_ID")
    private Long docTypeId;

    @ManyToOne
    @MapsId("personId")
    @JoinColumn(name = "PERSON_ID", referencedColumnName = "PERSON_ID")
    private Employee employee;
    ...
}

public class IdentityDocsPK implements Serializable {

    private Long personId;

    private Long docTypeId;
    ...
}

@Table(name = "PERSONS")
@Entity
@Where(clause = "PERSON_TYPE_ID = 1")
public class Employee {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    @Id
    private Long personId;
    ...
    @OneToMany(mappedBy = "employee", fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    private List<IdentityDocs> identityDocs;
}

@Table(name = "DOC_TYPES")
@Entity
public class DocTypes {

    @Id
    @Column(name = "DOC_TYPE_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long docTypeId;
    ...
}

Test case:

Employee employee = new Employee();
employee.setFirstName("AAAA");
employee.setLastName("BBBB");
employee.setPersonNumber("1337");

IdentityDocs docs1 = new IdentityDocs();
docs1.setDocTypeId(1L); // already in database
docs1.setDocNumber("11111");
docs1.setDocSeries("11111");
docs1.setPlaceIssue("1111");

employee.setIdentityDocs(new ArrayList<IdentityDocs>());
employee.getIdentityDocs().add(docs1);

em.persist(employee); 

Error code:

NULL not allowed for column "PERSON_ID"; SQL statement:
insert into IDENTITY_DOCS (DATE_EXPIRED, DATE_ISSUE, DOC_NUMBER, DOC_SERIES, PLACE_ISSUE, DOC_TYPE_ID, PERSON_ID) values (?, ?, ?, ?, ?, ?, ?) 

I also tried without @MapsId (using insertable = false, updatable=false on relevant field), but with same result. Question @OneToMany and composite primary keys? is relevant, but i dont find answer there

Community
  • 1
  • 1

1 Answers1

0

Maybe should have an AUTO_INCREMENT clause on your person_id field in your DDL, or generate the key in some other way.

HWJ
  • 77
  • 5
  • Key generation is ok (i suppose), but i use shared keys e.g. IdentityDocs.personId must be equal to Employee.personId. I think problem is in persisting order or JPA somehow missing to set IdentityDocs.personId after Employee was persisted. Everything works with one to one relationship and without composite key. – Andrew Petrov Jun 23 '15 at 12:27
  • Is your Person_id set to a non null value when you insert the record? Otherwise the error message is expected given the table definition. – HWJ Jun 23 '15 at 13:39
  • No, it set to null, because i create new records in db and expect orm to share id from Employee to IdentityDocs after Employee persisted. For Employee (PERSONS table) i have autoincrement serial. It works with OneToOne non-composite key (removing docTypeId from key). – Andrew Petrov Jun 24 '15 at 07:50