-->
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.  [ 2 posts ] 
Author Message
 Post subject: Flush problem when validating a lazy collection
PostPosted: Thu Jun 26, 2008 6:23 am 
Newbie

Joined: Tue Jun 17, 2008 7:45 am
Posts: 4
Dear all,

When I apply validation like @Size to a collection that is lazy loaded, I get the following error:

Code:
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: collection [...] was not processed by flush()
   at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:205)
   at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:333)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:28)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
   at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:456)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
   at
...


I have searched and found a similar, unresolved, issue in Hibernate JIRA:

http://opensource.atlassian.com/project ... owse/HV-37

However, my problem is with collection of entities, not composite-element as in HV-37.

I have look in to the Hibernate Validator code and found that in ClassValidator, member of a class is validated if it is already initialized. This check is done using Hibernate.isPropertyInitialized(). The following is the code copied from ClassValidator.InvalidValue[] getInvalidValues(T bean, Set<Object> circularityState)

Code:
      for ( int i = 0; i < memberValidators.size() ; i++ ) {
         XMember getter = memberGetters.get( i );
         if ( Hibernate.isPropertyInitialized( bean, getPropertyName( getter ) ) ) {
            Object value = getMemberValue( bean, getter );
            Validator validator = memberValidators.get( i );
            if ( !validator.isValid( value ) ) {
               String propertyName = getPropertyName( getter );
               results.add( new InvalidValue( interpolate(validator), beanClass, propertyName, value, bean ) );
            }
         }
      }



In my case Hibernate.isPropertyInitialized always return true, since my entity is not proxied, but its collection member is. The Hibernate code for isPropertyInitialzied is as follow (decompiled using Jad):

Code:
    public static boolean isPropertyInitialized(Object proxy, String propertyName)
    {
        Object entity;
        if(proxy instanceof HibernateProxy)
        {
            LazyInitializer li = ((HibernateProxy)proxy).getHibernateLazyInitializer();
            if(li.isUninitialized())
                return false;
            entity = li.getImplementation();
        } else
        {
            entity = proxy;
        }
        if(FieldInterceptionHelper.isInstrumented(entity))
        {
            FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor(entity);
            return interceptor == null || interceptor.isInitialized(propertyName);
        } else
        {
            return true;
        }
    }


For my entity, calling this method for any of it member will fall to the last else case returning true.

So, I try changing the Hibernate Validator code into:

Code:
      for ( int i = 0; i < memberValidators.size() ; i++ ) {
         XMember getter = memberGetters.get( i );

         if ( Hibernate.isPropertyInitialized( bean, getPropertyName( getter ) ) ) {
            Object value = getMemberValue( bean, getter );
        if ( value == null || Hibernate.isInitialized( value ) ) {
          Validator validator = memberValidators.get( i );
          if ( !validator.isValid( value ) ) {
            String propertyName = getPropertyName( getter );
            results.add( new InvalidValue( interpolate(validator), beanClass, propertyName, value, bean ) );
          }
        } else {
          log.info("Unintialized value not validated: "+getPropertyName( getter ));
        }
         }
      }


and the problem seems to be disappeared. The nearby code that validate child entity also perform some check like this. Since I'm new to Hibernate and Hibernate Validator, I am not sure if my modification will really work and why this check is not performed in the first place. So, could you guys please give me some suggestions?

I'm using:
Hibernate 3.2.6 GA,
Hibernate Annotation 3.3.1 GA,
Hibernate EntityManager 3.3.2 GA,
Hibernate Validator 3.0.0 GA

Thank you in advance,
Pongtawat


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 02, 2008 5:48 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

this might still be a bug. Maybe you could create a jira issue and attach a test case? Then we could validate ;-) the issue. It might be related to the already existing issue you've mentioned.

Without looking at the code I am not able say whether your workaround is ok.

--Hardy


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