Reputation: 117
I have edited my question after the answer of IntelliData.
In database i have, and i can't do any changes :
Table A {
ID NUMBER(10, 0) NOT NULL
DATE_DEBUT DATE NOT NULL
DATE_FIN DATE
.....
}
Table B {
ID NUMBER(10, 0) NOT NULL
B_ID VARCHAR2(10 BYTE) NOT NULL
}
In table A ID is PK, and it's a generated value.
In table B (ID, B_ID) is PK.
B.ID is FK on A.ID.
@Entity
@Table(name = "A")
public class A implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "aIdGenerator")
@SequenceGenerator(name = "aIdGenerator", sequenceName = "A_SEQ", allocationSize = 1)
@Column(name = "ID")
private Integer id;
@Column(name = "DATE_DEBUT")
private LocalDate dateDebut;
@Column(name = "DATE_FIN")
private LocalDate dateFin;
@OneToMany(mappedBy = "a", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
private List<B> bs;
.
.
.
}
@Entity
@Table(name = "B")
public class B implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "ID", referencedColumnName = "ID")
private A a;
@Id
@Column(name = "B_ID")
private String bID;
public B(final A a, final String bID) {
super();
this.a = a
this.bID= bID;
}
.
.
.
}
public interface aRepository extends JpaRepository<A, Integer> {
// nothing more
}
A a= new A();
a.setDateDebut(LocalDate.now());
a.setDateFin(LocalDate.now());
B bs = new ArrayList<B>();
bs.add(new B(a, "aaa"));
bs.add(new B(a, "bbb"));
bs.add(new B(a, "ccc"));
a.setBs(bs);
myrepo.saveAndFlush(a);
ORA-01400: cannot insert NULL into ("B"."ID") ---> RESOLVED by IntelliData
But now I get
ORA-02291: integrity constraint (FK_B_ID) violated - parent key not found
And I don't understand why because Hibernate insert in the good order AND WITH GOOD VALUES... I managed to get those logs :
DEBUG [main] org.hibernate.SQL(109) - insert into GOELAND_DEPLOI (DATE_DEBUT, DATE_FIN, ID) values (?, ?, ?)
Hibernate: insert into A (DATE_DEBUT, DATE_FIN, ID) values (?, ?, ?)
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [1] as [DATE] - [2016-06-22]
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [1] as [DATE] - [2016-06-22]
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [2] as [DATE] - [2016-06-22]
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [2] as [DATE] - [2016-06-22]
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [3] as [INTEGER] - [127]
DEBUG [main] org.hibernate.SQL(109) - insert into B (ID, B_ID) values (?, ?)
Hibernate: insert into B (ID, B_ID) values (?, ?)
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [1] as [INTEGER] - [127]
TRACE [main] o.h.t.d.sql.BasicBinder(81) - binding parameter [2] as [VARCHAR] - [TEST]
DEBUG [main] o.h.e.j.spi.SqlExceptionHelper(139) - could not execute statement [n/a]
java.sql.SQLIntegrityConstraintViolationException: ORA-02291: violation de contrainte d'intégrité (COMMON.FK_B_ID) - clé parent introuvable
If it's not enought I can put more logs that appear on myrepo.saveAndFlush(a);
Upvotes: 1
Views: 5180
Reputation: 121
It's seem that another one change your ID. Are you sure to not have a trigger on your A table which update the value
eg :
Hibernate : seq.nextVal => 52
Hibernate : insert into A values (52...)
Database : trigger on insert A : call to seq.nextVal => 53
Databse : Value really inserted into A : 53
Hibernate didn't know the value has changed.
Two solution :
Upvotes: 1
Reputation: 432
In order for b.ID to have a value, you must add a to b, as in :
b.setA(a);
The constructor for B sets the field b.bId, but not the field b.a ...
UPDATE:
Try changing this:
@OneToMany(mappedBy = "a", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
private List<B> bs;
to this:
@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name="ID")
@NotNull
private List<B> b;
Similar to the answer on this post. Please let me know if it worked.
Upvotes: 1