-->
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.  [ 4 posts ] 
Author Message
 Post subject: Custom UserType, entityManager and AssertionFailure
PostPosted: Mon Feb 08, 2010 5:23 am 
Newbie

Joined: Mon Sep 24, 2007 11:25 am
Posts: 4
Hi,

I'm trying to develop a custom type in hibernate to hold i18n fields. For that purpouse, I have created a custom Hibernate UserType.The problem is that whenever I need to save my entity, I also need to perform some queries inside the nullSafeSet() method. This works pretty good if all I do is :
Code:
entityManager.merge()


but when creating a straight new entity and calling entityManager.persist() it returns the following error:
Code:
10:14:12,018 ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in com.amadeus.websolutions.irmap.model.Airport entry (don't flush the Session after an exception occurs)


To create the queries inside the nullSafeSet method, I inject the Seam EntityManager component, which is basically a proxy to the entityManager. It does work when merging, not when persisting. The id field of my entity has Auto Generation.

Can someone bring some light into this? If I remove every entityManager query from my nullSafeSet() method it works, but I can't afford that.

Thank you in advance, and if you need more information, please just ask me.


Top
 Profile  
 
 Post subject: Re: Custom UserType, entityManager and AssertionFailure
PostPosted: Mon Feb 08, 2010 9:59 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I have not used user-types myself, but have some experience with the Interceptor interface. In this interface it is clearly stated that it is not allowed to use the current session or trigger lazy initialization of proxies or collections. I guess the reason is to not mess up the internal state of the session or to cause infinite loops, etc. I think the same restrictions may apply to user-types and probably for all other code that can be executed "inside" the session.

In some cases I also had to execute queries inside the Interceptor code. The way I solved it was to create a stateless session using the same connection as the primary session and then used this temporary session for executing queries. Something like this:

Code:
StatelessSession ss = sessionFactory.openStatelessSession(session.connection());
ss.createQuery(....);


I guess it would work to use a second regular session as well. Unfortunately the session.connection() method has been deprecated and there is yet no replacement for this scenario. I could have implemented this with the Work interface and plain SQL but I prefer HQL...

Hope this may be some help for you.


Top
 Profile  
 
 Post subject: Re: Custom UserType, entityManager and AssertionFailure
PostPosted: Mon Feb 08, 2010 10:13 am 
Newbie

Joined: Mon Sep 24, 2007 11:25 am
Posts: 4
Hi nordborg, thank you for your answer. The strange thing here is that if I'm merging an object (the object is managed) and not persisting it, everything works just fine. I also discovered that if I set the flushMode to COMMIT, I can use my entityManager to call the queries but the preparedStatement that I receive in the nullSafeSet method is already closed, so I get another error... :( Does this make any sense to you?

Also inside the nullSafeSet() method I don't have any session, just a PreparedStatement... I'm kind of lost here really.

Thank you very much for your reply.


Top
 Profile  
 
 Post subject: Re: Custom UserType, entityManager and AssertionFailure
PostPosted: Mon Feb 08, 2010 2:37 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Does this make any sense to you?


Well... I don't know the internals well enough to say if it makes sense or not. I guess you will see all kinds of strange behavior depending on the circumstances. For example, if you are using FlushMode.AUTO a query may trigger a flush and if your user-type code is invoked due to a flush in the first place there is likely to be some kind of clash.

Quote:
Also inside the nullSafeSet() method I don't have any session....
To create the queries inside the nullSafeSet method, I inject the Seam EntityManager component....


Isn't an entity manager "just a wrapper" around a session? You may have to dig a bit (and cast) but I think it should be possible to get the underlying session somehow. I have not used Seam though so I don't know for sure...

In any case... the PreparedStatment.getConnection() object should get you a connection and then it should be possible to create a Session with SessionFactory.openSession(Connection). I also came to think about that the reason that I need the connection from the main session is that I use the Interceptor to insert data to a log table. With this information it is possible to check when a specific entity was modified and by who. But I don't want to log anything if the main transaction fails and by using the same underlying connection a rollback will undo the log inserts as well as any other modifications. If you just need to query it may just as well work to open a second session using a new connection.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.