-->
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: Loading data from a database upon entity validation
PostPosted: Fri May 07, 2010 6:53 am 
Newbie

Joined: Thu May 06, 2010 11:36 am
Posts: 5
Location: Munich, Germany
Hi *,

I have the following scenario: An entity has quite a few custom validators attached (at property level as well as at class level), and for most of them the validation basically consists of checking the properties against a list of valid values. Also, not all combinations of property values are valid, so in addition to the single values having to be valid, they also must match one another. This cannot be implemented using a general algorithm, so I have to load the list of valid (single) values and the valid combinations of values from a database.

Implementing this as a set of custom Hibernate validators implies that every time these validators are run, they query the database. In particular, the validators seem to be invoked one last time before flushing the entities down to the database. The "real problem" with this (besides minor performance penalty) is that this seems to interfere with the currently ongoing flush of the entity manager, so the ultimate result is an IndexOutOfBoundsException within the ActionQueue.executeActions(List) method -- for some reason, the list of current actions that this method iterates is cleared "behind its back" during the execution of a single action (the one that queries the database) so when executeActions() does the next iteration, it gets the IOOBE. (See below.)

Well on the one hand, IMHO this should actually not happen within Hibernate code -- first, if there is a general problem, it should be reported as such with a meaningful exception message, and second, iterating the list over its iterator instead of "the array way" would have prevented this and/or thrown the more meaningful ConcurrentModificationException.

But on the other hand, I'd like to ask if if is generally OK to perform DB queries within custom validator code? In my case, the validator runs the query through the same entity manager that is currently flushing (and invoking the validator as a side effect). Is that OK? Or should I use a separate entity manager for such situations? Or maybe my use case is generally not what custom validators are intended for, so I should better do this kind of validation "the old way" instead of through annotated validations? (This would have the added benefit that I only validate when the affected properties actually changed, and not every single time the entity is persisted.)

If the given approach itself is OK, what could be the reason for this issue?


Thanks for any ideas,

Mike


Further information: I am using Hibernate 3.3.2 as part of JBoss Seam 2.2 on a JBoss 4.2 server. Here the relevant exception stack trace and the relevant code snippet from Hibernate code:

Code:
Caused by: java.lang.IndexOutOfBoundsException: Index: 2, Size: 0
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)
        at java.util.ArrayList.get(ArrayList.java:322)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
        at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504)
        ... 62 more


Code:
260:   private void executeActions(List list) throws HibernateException {
261:      int size = list.size();
262:      for ( int i = 0; i < size; i++ ) {
263:         execute( ( Executable ) list.get( i ) );
264:      }
265:      list.clear();
266:      session.getBatcher().executeBatch();
267:   }

_________________
There are 10 kinds of people -- those who understand binary, and those who don't


Top
 Profile  
 
 Post subject: Re: Loading data from a database upon entity validation
PostPosted: Fri May 07, 2010 11:57 am 
Newbie

Joined: Thu May 06, 2010 11:36 am
Posts: 5
Location: Munich, Germany
OK, so maybe the original posting was a bit too lengthy :-) Let's sum it up this way:

Is it OK to run queries from within custom validators, using the entity manager that manages the entity currently being validated?


Thanks a lot!

Mike

_________________
There are 10 kinds of people -- those who understand binary, and those who don't


Top
 Profile  
 
 Post subject: Re: Loading data from a database upon entity validation
PostPosted: Fri May 07, 2010 1:04 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I think you more or less answered your question in the first post. It is not ok to call/use the same session in any callback methods that are triggered from the session. It goes for Interceptor:s, EventListener:s, UserType:s, etc, and includes proxy and lazy collection initialization.

It should work well with a different session. The second-level cache can be used to reduce the performance penalty.


Top
 Profile  
 
 Post subject: Re: Loading data from a database upon entity validation
PostPosted: Fri May 07, 2010 2:54 pm 
Newbie

Joined: Thu May 06, 2010 11:36 am
Posts: 5
Location: Munich, Germany
Hi nordborg,

Thanks a lot for your reply! In the meantime, I already found out that it works with a separate session (or rather, an entityManager in Seam). I just wasn't sure if this was a "coincidence" or if my approach was outright wrong, since it works "sometimes" and sometimes not, and I couldn't seem to find any reasonable cause of when it works and when it doesn't (although it is always reliably reproducible).

Nevertheless, shouldn't the Hibernate runtime detect such situations and report them meaningfully? I mean, noting a flag that a callback is currently running is not a great deal of complexity, and the runtime already detects so many other, more complex things -- I newly spent two days debugging a "found shared references to a collection" error. Besides, the way that this IOOBE occurs just should not happen -- this is like having an (unintended) NPE or some other "trivial" thing :-)

Anyway, thanks for your hint, now I know how to do it right!


Have a nice friday evening (= not in front of the PC :-)),

Mike

_________________
There are 10 kinds of people -- those who understand binary, and those who don't


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.