• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

SCBCD 5.0 question about merging a removed entity

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I have a problem with the code snippet below regarding the JPA 1.0 spec. about merging entity :” If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).”

The code sample :
Employee emp =new Employee("Paul",1500);//NEW
em.persist(emp);//1- MANAGED
//em.flush(); //works as expected if uncommented
em.remove(emp);//2- REMOVED
Employee managedEmp= em.merge(emp);//3- should throw IllegalArgumentException BUT NO

Additional informations :
This code execute within a stateless session bean’s method whith transaction attribute REQUIRED (in my case start a transaction)

The persistence context is transaction-scoped. Instance variable em references an injected entity manager

The Employee entity class as an id generated with the IDENTITY strategy (primary key created during the sql insertion when the transaction commits)

I’m using Glassfish Enterprise Server v2.1.1 ((v2.1 Patch06)(9.1_02 Patch12)), with Toplink essentials as persistence provider .

So my problem is that regarding the specification, the second call to merge on an entity in REMOVED state should throw IllegalArgumentException. If I use em.flush(), the behavior is the one expected : the exception is thrown. But without an explicit flush there is no exception.

But, if I have well understood the spec, when I call persist on a new instance, this instance becomes MANAGED (even if the id will be generated during insertion). When I call next remove() on the same instance, it becomes REMOVED. So the next call to merge() should throw IllegalArgumentException.

What can I have missed ? must I consider that my Employee instance is REALLY MANAGED only after the insertion in the database ? Is there a problem whith toplink essentials ?...

Hope I was enough clear. Thank you by advance
Regards,
Alexandre
 
Ranch Hand
Posts: 100
Hibernate Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
In case if you are still looking for the answer, found the following info

Just like persist, invoking remove on an entity does NOT cause an immediate SQL DELETE to be issued on the database. The entity will be deleted on the next invocation of EntityManager#flush() that involves that entity. This means that entities scheduled for removal can still be queried for and appear in query and collection results.


at webpage
So, if explicit flush call is not invoked, the SQL queries will get queued up to be executed in bulk during the default flush that happens at the transaction commit time. And, there seems to be an order in which the SQL queries are fired on the database(atleast in case of hibernate.. more info at webpage.
Here, entity removal is executed last. The same might be happening in your scenario with TopLink as well.
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,

its a good question, as you wrote:
"If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail)."

if it doesnt throw an IllegalArgumentException your transaction wont fail.
It's not strictly described by the specification.
the main goal is to prevent the database from illegal updates/inserts.
and in your case you dont have illegal updates/insterts

however it's strange..
eclipselink/toplink doesnt throw IllegalArgumentException, but hibernate does.
 
Alexandre Sbriglio
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, thanks for all your replies.
Although toplink is the IR, I think this time, Hibernate has a behaviour more in-phase with the specification.
I agree that sql order are deferred at the end of the transaction, but if I understood the spec, the IllegalArgumentException's throwing has more to do with entity's state than sql order because we can't exactly rely when the sql orders will be send. For me after calling remove(), the entity is in removed state, so it sh'ould be forbidden to call merge on it.

regards,
 
Tamas Polgar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hibernate is quite far from the spec, if you want to play with nested embeddables, and element collections, you could have problems with hibernate.
eclipselink's behaviour is ok by the spec.

but hibernate builds much better queries than openjpa/eclipselink.

we can choose from different implementations fortunately
 
reply
    Bookmark Topic Watch Topic
  • New Topic