-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: merge question
PostPosted: Thu Apr 13, 2006 3:19 am 
Regular
Regular

Joined: Sat Jan 07, 2006 8:30 pm
Posts: 68
Hi,

I have a participant table that I mapped. Everything worked fine till this point when I decided to try the merge().

I have a webpage that allows me to modify a Participant entity. As is normal only a limited number of fields from Participant are going to be edit enabled.

So, when I click submit I endup having an incomplete Participant and I want to merge it with the persisted instance.

Participant has some fields declared as not null as below

<property name="paxStatus" type="string">
<column name="pax_status" length="9" not-null="true" />
</property>

When I did the merge I get this error...

2006-04-13 01:46:08,921 ERROR org.hibernate.PropertyValueException: not-null property references a null or transient value: com.xyz.Participant.paxStatus

The error is normal for a saveUpdate but I thought this case should be managed by merge()...


To me seems that it copies over the null value from the web object

at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:256)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:114)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at com.xyz.HibernateSessionInterceptor.invoke(HibernateSessionInterceptor.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)


What do you think ?
Q


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 4:11 pm 
Regular
Regular

Joined: Sat Jan 07, 2006 8:30 pm
Posts: 68
Is it a must to have a version in my mapping ?

<version name="version" column="VERSION" type="java.lang.Long" />

That implies that I have to persist this to database too ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 4:51 pm 
Regular
Regular

Joined: Sat Jan 07, 2006 8:30 pm
Posts: 68
From documentation...looks like a recommandation though..

"We very strongly recommend that you use version/timestamp columns for optimistic locking with Hibernate.
This is the optimal strategy with respect to performance and is the only strategy that correctly handles modifications
made to detached instances (ie. when Session.merge() is used)."


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 8:44 pm 
Regular
Regular

Joined: Wed Jul 07, 2004 2:00 pm
Posts: 64
The idea of merge is that it takes a POJO and updates all of the mapped properties and updates the database. Hibernate knows nothing of your UI, and merge doesn't allow you to specify that only a few properties should be considered. It can't tell that a null value in a mapped property means that this should not be written to the database. In addition, how would it tell the difference between a property that is null because it wasn't copied from the UI, versus a property that is null because the UI set it null from an empty field. In order to get the merge to work in this case, you will probably have to retrieve a participant from the database, then update any properties from UI fields, and send the resulting fully-populated participant back to the merge.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 13, 2006 9:12 pm 
Regular
Regular

Joined: Sat Jan 07, 2006 8:30 pm
Posts: 68
But then what's the difference between saveOrUpdate and merge();
I really don't see why one would use merge over saveOrUpdate - I will re-read what they say about merge()...

Basically you're saying that prior to merge to do a load myself and overwrite only those fields that I'm capturing from the web. Well, this was the backup plan hoping that merge will merge indeed the values that are not null with the already persitsted entity.

So it doensn't do that...


Q


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 3:12 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Urrr...is the NHibernate related? Sounds like Hibernate 3.0 features to me...or are we starting to see these in NHibernate?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 1:43 pm 
Regular
Regular

Joined: Sat Jan 07, 2006 8:30 pm
Posts: 68
True! Wrong forum - I did a search and then I replied!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 10:17 pm 
Regular
Regular

Joined: Wed Jul 07, 2004 2:00 pm
Posts: 64
Merge is part of the new java persistence API, while saveOrUpdate is Hibernate-specific. Both appear to work for disconnected entities, but I have found advantages to merge in the area of collections. Lets say you have a
class Person {
private List phones = new ArrayList();...

Hibernate replaces the ArrayList with a PersistentBag when a Person is loaded from the database.

OK, so who cares?

Well, what if you're serializing the Person and passing it on to some VM that doesn't have the Hibernate library?

I have such a case with my web services. The client doesn't have Hibernate, so a Person passed to the client will only have an ArrayList. Then, it passes it back to the server to be saved. If the client has changed a phone, both merge and saveOrUpdate work. But if the client deleted a phone, saveOrUpdate won't delete it from the database, even if the mapping cascade included delete-orphan. Merge, however, will properly delete it.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 03, 2006 12:39 pm 
Newbie

Joined: Wed May 03, 2006 8:50 am
Posts: 1
DWright wrote:
... If the client has changed a phone, both merge and saveOrUpdate work. But if the client deleted a phone, saveOrUpdate won't delete it from the database, even if the mapping cascade included delete-orphan. Merge, however, will properly delete it.


But ... I noticed that if a new phone (with no id) is added to the client, merge will not work while saveOrUpdate will correctly create the new phone entry. How do you solve this problem using merge?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.