-->
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: entity snapshots deserialization (StatefulPersistenceCtx)
PostPosted: Wed Sep 24, 2014 2:45 am 
Newbie

Joined: Thu Aug 21, 2014 1:42 am
Posts: 3
I have a problem with hibernate 4.3.6 and spring webflow 2.4.1.

I don't use a store for the flows so the persistence context is linked to the HTTP session and when changing page in the flow it calls a deserialization/serialization of the hibernate session.

At a moment in the flow, i have 3 new entities (referencing each other), those are stored in the entitySnapshotsByKey map of the org.hibernate.engine.internal.StatefulPersistenceContext with the static final property NO_ROW as value (from org.hibernate.engine.spi.PersistenceContext).

When going to the next page deserialization/serialization of the hibernate session is done. The next call to persist() will check if the new entity already exists in the cache using the method : org.hibernate.engine.internal.StatefulPersistenceContext.getDatabaseSnapshot(Serializable, EntityPersister).
The problem is, ithe following piece of code of this method :

Code:
if ( cached != null ) {
        return cached == NO_ROW ? null : (Object[]) cached;
    }
    else {
        final Object[] snapshot = persister.getDatabaseSnapshot( id, session );
        entitySnapshotsByKey.put( key, snapshot == null ? NO_ROW : snapshot );
        return snapshot;
    }


The cached values are in the map (they are deserialized at this moment) so the following line is executed :

Code:
return cached == NO_ROW ? null : (Object[]) cached;


"cached" has indeed the value NO_ROW but not the same reference than the static final field of PersistenceContext because it was deserialized so "cached == NO_ROW" will never be true and the MarkerObject will be casted to Object[]!

My opinion is that the method public static StatefulPersistenceContext deserialize(ObjectInputStream ois, SessionImplementor session) is incomplete.

It causes the following ClassCastException :
Code:
java.lang.ClassCastException: org.hibernate.internal.util.MarkerObject cannot be cast to [Ljava.lang.Object;
at org.hibernate.engine.internal.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:313)
at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:255)
at org.hibernate.engine.internal.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:177)
at org.hibernate.engine.internal.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:105)
at org.hibernate.engine.internal.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:81)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:130)
at org.hibernate.action.internal.AbstractEntityInsertAction.makeEntityManaged(AbstractEntityInsertAction.java:141)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:201)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:166)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:332)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at core.dao.generic.AbstractHibernateDao.persist(AbstractHibernateDao.java:45)
at web.flow.controller.DenoFlowController.saveDenomination(DenoFlowController.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:63)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:95)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:44)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:258)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:84)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:105)
at org.springframework.binding.expression.spel.SpringELExpression.getValue(SpringELExpression.java:84)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:75)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.engine.support.ActionTransitionCriteria.test(ActionTransitionCriteria.java:82)
at org.springframework.webflow.engine.support.TransitionCriteriaChain.test(TransitionCriteriaChain.java:68)
at org.springframework.webflow.engine.Transition.canExecute(Transition.java:196)
at org.springframework.webflow.engine.Transition.execute(Transition.java:212)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ViewState.handleEvent(ViewState.java:231)
at org.springframework.webflow.engine.ViewState.resume(ViewState.java:195)
at org.springframework.webflow.engine.Flow.resume(Flow.java:537)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:228)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)


It seems to be a bug but i can't believe that i'm the first one encountering this issue because apparently this piece of code hasn't changed in years.

Did someone already have a similar problem?

I clearly don't see what i'm doing wrong as it's all hibernate internal business.

Thanks.

Edit : Created JIRA ticket https://hibernate.atlassian.net/browse/HHH-9414


Last edited by Quent on Wed Sep 24, 2014 5:36 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: entity snapshots deserialization (StatefulPersistenceCtx)
PostPosted: Wed Sep 24, 2014 3:03 am 
Newbie

Joined: Thu Aug 21, 2014 1:42 am
Posts: 3
Small test to illustrate the problem with MarkerObject:
Code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.hibernate.engine.spi.PersistenceContext;

public class TestMarkerObjectSerialization {

   public static void main(String[] args) {
      Object noRowDeserialized = null;
      try {
         FileOutputStream fileOut = new FileOutputStream("/tmp/no_row.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(PersistenceContext.NO_ROW);
         out.close();
         fileOut.close();

         FileInputStream fileIn = new FileInputStream("/tmp/no_row.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         noRowDeserialized = in.readObject();
         in.close();
         fileIn.close();
      } catch (IOException i) {
         i.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }
      if (PersistenceContext.NO_ROW != noRowDeserialized) {
         throw new RuntimeException("Reference checking is wrong after serialization");
      }
   }

}


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.