JPA merge isn't working as expected - merge of object ignoring filled values from object

2,827 views
Skip to first unread message

Sean Van Buggenum

unread,
Jan 14, 2016, 12:10:31 PM1/14/16
to play-framework
hi all, 

I'm having trouble with the JPA EntityManager merge method. 

So far as I read, i.e., from sources such as stackoverflow
the merge method should be more helpful than it is appearing to me at the moment. 

I am attempting to write a new record to the database based on an object that I have no way of knowing is already persisted or not. 

The class is this:

@Entity
public class IdType implements Persistable
{
 
/**
 * User specified Unique identifier.
 * Both idTypeCode and idCategory are together
 * a compound key, so as to ensure that the
 * combination of the both can not occur more
 * than once in the table.
 */

 
@Id
 
public String idTypeCode;
 
@Id
 
public IdCategory idCategory;
 
 
public String idTypeName;
}


And when I call 'merge' on it, I get a big nasty stack trace about one of the id fields (from the composite idTypeCode and idCategory)   idtypeCode being null (which is not allowed, obviously). 

Yet I know the instance of this class DOES have a value for idTypeCode, as in my controller, I am binding the form and then for debugging purposes i'm sys-outing the values. 

The code:


 
@Transactional
 
public Result updateIds()
 
{
 
IdType idType = Form.form(IdType.class).bindFromRequest().get();


 
System.out.println("idTypeCode is:  "+idType.idTypeCode);
 
 
EntityManager em = entityManager();
 em
.merge(idType);



 
return redirect(routes.Application.index());
 
}





The console:


idTypeCode
is:  a-value-from-my-form
[error] - org.hibernate.engine.jdbc.spi.SqlExceptionHelper - NULL not allowed for column "ID_TYPE_CODE"; SQL statement:
insert
into id_type (id_type_name, id_type_code, id_category) values (?, ?, ?) [23502-187]
[error] - play.core.server.netty.PlayDefaultUpstreamHandler - Cannot invoke the action
javax
.persistence.RollbackException: Error while committing the transaction
 at org
.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:86) ~[hibernate-entitymanager-5.0.5.Final.jar:5.0.5.Final]
 at play
.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:142) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]
 at play
.db.jpa.JPA.withTransaction(JPA.java:159) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]
 at play
.db.jpa.TransactionalAction.call(TransactionalAction.java:16) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]


Does anyone know the cause of this problem ? 

I hope I am not forced to call 'persist' instead, as I have no way of knowing if the entity exists already in the database. 

thanks for your help!

sean

Sean Van Buggenum

unread,
Jan 22, 2016, 2:39:01 AM1/22/16
to play-framework
Not so easy a question eh?
I'm sorry if I phrased it incorrectly, or didn't get to the point as good as I should have. 
But I would like to hear anyway of success stories from people using pure JPA with Play, 
and how they got around the problem of a lack of a hibernate equivalent 'saveOrUpdate' method.
That was my hopes with the 'merge' method. However, honestly, I have not tested this (pure JPA using Hibernate) with a non-play project as yet to see how it behaves out of the 'play eco-system'. 
That will be my next step. And as soon as my boss allows me to dedicate more time (in about a week) I will be back at it. 
Until then, I'd love to hear of peoples success or lackthereof. 

Regards,

Sean

Sean Van Buggenum

unread,
Feb 2, 2016, 8:11:26 AM2/2/16
to play-framework

UPDATE!!!!!

OK, finally got the time to look further into this myself. It seems this has nothing to do with play. I tested just now the same scenario with a straight JPA/Hibernate console app. I get the same problem. The problem occurs as soon as I have a composite key (as I do in the given example). As soon as I remove one of the columns as key, the merge will work. Now I am investigating why that is, and how to avoid the issue (while still having the model I need). I will update this issue as soon as I have more information.



On Thursday, 14 January 2016 18:10:31 UTC+1, Sean Van Buggenum wrote:

Sean Van Buggenum

unread,
Feb 2, 2016, 12:14:08 PM2/2/16
to play-framework
OK. So I worked it out finally.
It seems like I was constructing my JPA compound primary key incorrectly. 

I thought I could simply specify my compound key with the Id annotation alone. Like so:




@Entity
public class IdType implements Serializable
{
/**
* User specified Unique identifier.
* Both idTypeCode and idCategory are together
* a compound key, so as to ensure that the 
* combination of the both can not occur more
* than once in the table.
*/
@Id
public String idTypeCode;
@Id
public IdCategory idCategory;
public String idTypeName;
}

But I was wrong. 
I need to use a separate IdClass. Otherwise, I get cryptic error messages as described earlier. 
Now my class(es) look like this:


@Entity @IdClass(IdTypeCompoundId.class)
public class IdType implements Serializable
{
/**
* User specified Unique identifier.
* Both idTypeCode and idCategory are together
* a compound key, so as to ensure that the 
* combination of the both can not occur more
* than once in the table.
*/
@Id
public String idTypeCode;
@Id
public IdCategory idCategory;
public String idTypeName;
}


public class IdTypeCompoundId implements Serializable
{
public String idTypeCode;
public IdCategory idCategory;
}


and it is all happy.  Merge goes through without problems. 

pwew!




On Thursday, 14 January 2016 18:10:31 UTC+1, Sean Van Buggenum wrote:
Reply all
Reply to author
Forward
0 new messages