Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration(Insert and Delete problems with not nullable fields in Eclipselink)
Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730471] Tue, 26 April 2016 06:54 Go to next message
Thomas Kernstock is currently offline Thomas KernstockFriend
Messages: 27
Registered: July 2009
Location: Vienna
Junior Member
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?

thank you for your help

Thomas
Re: Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730533 is a reply to message #1730471] Tue, 26 April 2016 14:18 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1342
Registered: July 2009
Senior Member
This is not a JPA 2.0 -> JPA 2.1 issue, and I don't know why it would have worked on Glassfish 3.1.1 as it appeared to: EclipseLink has always handled setting unidirectional 1:M relationships in a separate update statement after inserting/updating the referenced entity, as described here https://bugs.eclipse.org/bugs/show_bug.cgi?id=392450

Solutions are
- to relax the constraint checking so that it occurs at the end of the transaction instead of on each statement,
- make relationships bi-directional, or
- add a mapping for the foreign key to the referenced entity and make the 1:m read-only

The feature filed to include the foreign key value in the statement used for the referenced entity can be referenced here https://bugs.eclipse.org/bugs/show_bug.cgi?id=391279



Re: Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730549 is a reply to message #1730533] Tue, 26 April 2016 15:36 Go to previous messageGo to next message
Thomas Kernstock is currently offline Thomas KernstockFriend
Messages: 27
Registered: July 2009
Location: Vienna
Junior Member
Hi Chris,
thank you for your answer. I will try the suggested changes.

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 interesting because on the new server I have the same update statement "UPDATE bewerbungen SET BewerberID = ?, ...." but there it fails immediately with the null constraint!

[Updated on: Tue, 26 April 2016 16:34]

Report message to a moderator

Re: Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730583 is a reply to message #1730533] Tue, 26 April 2016 21:31 Go to previous messageGo to next message
Thomas Kernstock is currently offline Thomas KernstockFriend
Messages: 27
Registered: July 2009
Location: Vienna
Junior Member
Hi Chris,

you wrote:

Chris Delahunt wrote on Tue, 26 April 2016 14:18
Solutions are
- to relax the constraint checking so that it occurs at the end of the transaction instead of on each statement,


I think this could be the solution because this constraint checking seems to be active on my productive systems right now (looking at the logs). But I couldn't find a way to change that behaviour.
Do you know what I have to do, to switch to "end of transaction checking"?

best
Thomas

Re: Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730658 is a reply to message #1730583] Wed, 27 April 2016 13:20 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1342
Registered: July 2009
Senior Member
It is database specific. If you are using the same database, check the datasource setup on the Glassfish instance that is working to see if some connection property was added that is missing in your new setup.
icon3.gif  Re: Uni-directional OneToMany problems with JPA2.0 -> JPA2.1 migration [message #1730674 is a reply to message #1730658] Wed, 27 April 2016 14:56 Go to previous message
Thomas Kernstock is currently offline Thomas KernstockFriend
Messages: 27
Registered: July 2009
Location: Vienna
Junior Member
Hi Chris

thank you very much for this hint.

I just changed the JDBC Definition from

<jdbc-connection-pool datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"  name="Test" res-type="javax.sql.DataSource">

to

<jdbc-connection-pool datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource" name="Test" res-type="javax.sql.ConnectionPoolDataSource">


Now the inserts and deletes work as before. Smile

BR
Thomas
Previous Topic:EclipseLink Moxy Dynamic JAXB strange behavior for standard XSD restrictions
Next Topic:Support for dynamic SQL from Expression API in predicates
Goto Forum:
  


Current Time: Sat Mar 28 22:08:16 GMT 2020

Powered by FUDForum. Page generated in 0.02036 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top