0

I am migrating client application from Hibernate to EclipseLink. But it is not inserting value for foreign key when calling persist method on student entity. Database is oracle. There is Many to one relation between Address and Student.

Also in generated SQL the foreign key column is not present.

@Entity
@Table(name = "Student", schema = "Student_DB")
@SequenceGenerator(name = "studentSeq", sequenceName = "Student_SEQ", schema = "Student_DB", allocationSize = 1)
public class StudentEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "studentSeq")
    @Column(name = "S_ID")
    private BigDecimal studentID;

    @OneToMany(mappedBy = "studentEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "S_ID")
    private List<AddressEntity> addresses;

}
addAddress(address){
  address.setStudentEntity(this);

@Entity
@Table(name = "Address", schema = "Student_DB")
@SequenceGenerator(name = "AddressSeq", sequenceName = "Address_SEQ", schema = "Student_DB", allocationSize = 1)
public class AddressEntity implements Serializable {

    @Id
    @Column(name = "A_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AddressSeq")
    private long addressID;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "S_ID", referencedColumnName = "S_ID", insertable = false, updatable = false, nullable = false)
    private StudentEntity studentEntity;
}

*

> [EL Fine]: sql: 2019-06-25
> 18:39:00.895--ClientSession(1656550367)--Connection(-872205654)--INSERT
> INTO Student_DB.Student (S_ID, ...) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,
> ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  bind => [24 parameters
> bound] [EL Fine]: sql: 2019-06-25
> 18:39:00.946--ClientSession(1656550367)--Connection(-872205654)--INSERT
> INTO Student_DB.Address (A_ID, CO...) VALUES (?, ?, ?, ?, ?)  bind =>
> [5 parameters bound] [EL Fine]: sql: 2019-06-25
> 18:39:00.954--ClientSession(1656550367)--SELECT 1 FROM DUAL [EL
> Warning]: 2019-06-25 18:39:00.955--UnitOfWork(-922357549)--Exception
> [EclipseLink-4002] (Eclipse Persistence Services -
> 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal
> Exception: java.sql.SQLIntegrityConstraintViolationException:
> ORA-01400: cannot insert NULL into ("Student_DB"."Address"."S_ID")

*

  • **It is not exact code but similar** – user3092515 Jun 25 '19 at 13:56
  • You have private List addresses; mapped with both OneToMany(mappedBy = "studentEntity") AND specify the @JoinColumn(name = "S_ID") annotation. MappedBy is used to indicate that the other side controls the foreign key, both the definition and the field, while JoinColumn conflicts with that and is used for unidirectional mappings. It can't be both, so you are ignoring some warnings during deployment, and since the AddressEntity.studentEntity reference is read-only, the field isn't getting set. – Chris Jun 25 '19 at 14:15
  • Hi Chris, thanks for your input, I tried with both options first by removing @join column and second by removing mappedby from student class but same result Error Code: 1400 Call: INSERT INTO Student_DB.Address (S_ID, DGFH, SGFFD, GHJG, GHJGH) VALUES (?, ?, ?, ?, ?) bind => [5 parameters bound] – user3092515 Jun 25 '19 at 14:41
  • Here in insert statement it should also include S_ID but I don't know why it is missing here :( – user3092515 Jun 25 '19 at 14:42
  • if you left the insertable=false, updatable=false, (but removed the join column) it means the foreign key is never set from that mapping. If you kept the joinColumn annotation, Eclipselink will update the foreign key in separate statement after the initial insert. You cannot use the join column unidirectional mapping and have a not-null constraint with EclipseLink. – Chris Jun 25 '19 at 18:36
  • OK Now I have better understanding. Thanks for your effort :) – user3092515 Jun 26 '19 at 05:44

1 Answers1

1

The correct mapping would look like:

@Entity
@Table(name = "Student", schema = "Student_DB")
@SequenceGenerator(name = "studentSeq", sequenceName = "Student_SEQ", schema = "Student_DB", allocationSize = 1)
public class StudentEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "studentSeq")
    @Column(name = "S_ID")
    private BigDecimal studentID;

    @OneToMany(mappedBy = "studentEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<AddressEntity> addresses;

}


@Entity
@Table(name = "Address", schema = "Student_DB")
@SequenceGenerator(name = "AddressSeq", sequenceName = "Address_SEQ", schema = "Student_DB", allocationSize = 1)
public class AddressEntity implements Serializable {

    @Id
    @Column(name = "A_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AddressSeq")
    private long addressID;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "S_ID", referencedColumnName = "S_ID", nullable = false)
    private StudentEntity studentEntity;
}
Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
  • Hi Simon, Thanks!!! for your effort. The suggested changes are working but just one question as it was existing code of client just wanted to know what was the purpose of insertable = false, updatable = false in address entity. As I know they should be there so that my address entity do not create or update student or am I wrong in understanding this concept? – user3092515 Jun 25 '19 at 14:55
  • They indicate that this column is read only. What was wrong. I'm happy to help.and appreciate if you would accept my answer as the correct answer – Simon Martinelli Jun 25 '19 at 16:19