If have a JEE6 application that works fine on Glassfish 3.1.1 since years. Now have to move it to JEE7 / Glassfish 4.1.1 and ran into a couple of problems regarding JPA / Eclipselink:
a) I have an entity Applicant that contains a couple of Lists mapped as uni-directional OneToMany relations.
@Entity
@Table(name="applicant")
@AttributeOverride(name="id", column=@Column(name="UserID", insertable=false, updatable=false))
public class Applicant extends BaseEntityVersioned implements Serializable {
..
..
@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="BewerberID", nullable=false)
private List<ITKenntnis> itKenntnisse = new ArrayList<ITKenntnis>();
..
public List<ITKenntnis> getITKenntnisse() {
return this.itKenntnisse;
}
public void setITKenntnisse(List<ITKenntnis> itKenntnisse) {
this.itKenntnisse = itKenntnisse;
}
public ITKenntnis createITKenntnis(){
return new ITKenntnis();
}
public boolean addITKenntnis(ITKenntnis itKenntnis) {
getITKenntnisse().add(itKenntnis);
return true;
}
...
}
and the entity ITKEnntnis
@Entity
@Table(name="ITKenntnis")
public class ITKenntnis extends BaseEntityVersioned implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Integer id;
@Override
public Integer getId() {
return id;
}
@Override
public void setId(Integer id) {
this.id=id;
}
}
Until now I simply added a new instance of ITKentnis to the applicant with addKenntnis and persisted the applicant. With Glassfish 4.1.1 I get an error ->
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.2.qualifier): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Field 'BewerberID' doesn't have a default value Error Code: 1364
The field "BewerberID" is a foreign key in my database table that cannot be null, and I can't change this definition.
The only workaround I found so far was to redefine the relationship to bi-directional. Since I have a lot of relations and the code worked with JPA 2.0, I would appreciate if there was a simpler solution.
b) I have an entity Application that defines a uni-directional @ManyToOne relationship to Applicant.
@Entity
@Table(name="bewerbungen")
public class Application extends BaseEntityVersioned implements Serializable {
...
// uni-directional
@ManyToOne (fetch=FetchType.LAZY)
@JoinColumn(name="BewerberID")
private Bewerberprofil bewerberprofil;
...
}
Regardless of wether this is a good design or not (I had reasons to map it that way) -> when I try to delete the entity I see an update that sets the field "BewerberID" to null, instead of a delete. Why is that in JPA 2.1 and how can I change that?
Sorry for the long post.
Thomas
EDIT: I made further investigations with these issues, debugging the SQL statements generated on the Glasfish 3.1.1. server that's working.
Adding a new child entity has the following SQL statements which are the same as on the new server ->
[#|2016-04-26T17:22:55.613+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.613--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--INSERT INTO bewerberedv (Bearbeitet, Bereich, Bewertung, Dauer, Kenntnis, Version, ZuletztVerwendet) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [true, 6, 1, null, 377, 2016-04-26 17:24:08.0, null]
|#]
[#|2016-04-26T17:22:55.628+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.628--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--SELECT LAST_INSERT_ID()
|#]
[#|2016-04-26T17:22:55.644+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.644--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--UPDATE bewerberedv SET BewerberID = ? WHERE (ID = ?)
bind => [2575, 1223970]
|#]
The difference is, that on the new server the INSERT fails because the field "BewerberID" can't be NULL. Somehow the check in the database seems to be different.
The same is for the DELETE which has following output ->
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE bewerbungen SET BewerberID = ?, PositionID = ?, InseratID = ?, Version = ? WHERE ((ID = ?) AND (Version = ?))
bind => [null, null, null, 2016-04-26 17:14:52.0, 1304157, 2016-04-26 17:14:25.0]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE inserateanz SET AnzahlBew = ?, AnzOffeneBewerbung = ?, AnzNeueBewerbung = ? WHERE (ID = ?)
bind => [0, 0, 0, 61277]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE positionenanz SET AnzahlBew = ?, AnzOffeneBewerbung = ?, AnzNeueBewerbung = ? WHERE (ID = ?)
bind => [0, 0, 0, 44726]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--DELETE FROM bewerbungen WHERE ((ID = ?) AND (Version = ?))
bind => [1304157, 2016-04-26 17:14:52.0]
Thats interresting because on the new server I have the same update statement "UPDATE bewerbungen SET BewerberID = ?, ...." but there it fails immediately with the null constraint!