2 Replies Latest reply on Oct 30, 2009 8:35 AM by chtimi2

    Is this a lazy loading issue? (not CacheLoader)

      I think i'm having a lazy-loading issue:

      I have to JVMs:
      -one with JBossPOJOCache (JBPC henceforth) in local mode (not replicated). On this JVM i have a class TracksTableImpl that implements its service interface by acting on an instrumented JBPC pojo TracksTableJbpcDelegate
      (On second thought it looks more like a Core issue than a POJO one)
      -one with a unit test that updates the remote state via a service call (remoting doesn't use JBPC), and then checks that the state is correct in case of a commit then a rollback

      Server-side service:

      public class TracksTableImpl implements TracksTable, TracksTableServices
      {
       private TracksTableJbpcDelegate delegate = new TracksTableJbpcDelegate ();
      
       @Override
       @Transactional
       public void updateXY ( double x , double y , boolean failOnUpdateY )
       {
       delegate.updateX ( x );
       if ( failOnUpdateY ) throw new TrackException ();
       delegate.updateY ( y );
       }
      
       @Override
       @Transactional
       public Position getPosition()
       {
       return delegate.getPosition();
       }
      }
      


      Server-side, the JBPC POJO:
      @org.jboss.cache.pojo.annotation.Replicable
      public class TracksTableJbpcDelegate
      {
       private List<ReadWriteTrack> tracks = new ArrayList<ReadWriteTrack> ();
      
       public void updateX ( double x )
       {
       ReadWriteKinematics k = getOrCreateReadWriteKinematics ();
       k.getReadWritePosition().setX ( x );
       }
      
       public void updateY ( double y )
       {
       ReadWriteKinematics k = getOrCreateReadWriteKinematics ();
       k.getReadWritePosition().setY ( y );
       }
      
       public Position getPosition()
       {
       Position ret = getUniqueTrack ().getKinematics().getPosition();
       //System.out.println ( "TracksTableJbpcDelegate/getPosition/ret.getX(): " + ret.getX() );
       //Navigating ret.getX: correct, up-to-date result
       //When commented: incorrect, rolled-back result
      
       return ret;
       }
      
       public ReadWriteTrack getUniqueTrack()
       {
       if ( tracks.size() != 1 ) throw new IllegalStateException ( "Cette methode ne peut etre appelee que si la liste contient un unique element" );
       ReadWriteTrack ret = tracks.get ( 0 );
       //System.out.println ( "TracksTableJbpcDelegate/getUniqueTrack/ret.getX(): " + ret.getKinematics().getPosition().getX() );
       return ret;
       }
      }
      

      Of course Position is also instrumented (@Replicable).

      Client side, the test:
      @Test
       public void atomiciteUpdate3 () throws Exception
       {
       table.createTrack ( false );
       assertEquals ( 1 , table.size() );
      
       final double X_OK=111d, Y_OK=222d, PRECISION=0.001d;
       table.updateXY ( X_OK , Y_OK , false );
       assertEquals ( X_OK , table.getPosition().getX() , PRECISION );
       assertEquals ( Y_OK , table.getPosition().getY() , PRECISION );
      
       try
       {
       final double X_KO=333d, Y_KO=444d;
       table.updateXY ( X_KO , Y_KO , true );
       fail ();
       }
       catch ( Exception e ) {}
       finally
       {
       assertEquals ( Y_OK , table.getPosition().getY() , PRECISION );
       assertEquals ( X_OK , table.getPosition().getX() , PRECISION );
       }
       }


      When the argument failOnUpdateY of method TracksTableImpl updateXY is true, the transaction is rolled back. This works correctly, that isn't the issue.

      The issue is that when the bold underscored log is uncommented, the test passes, while it doesn't if it's commented.
      Plus the same test with JBPC and the test in the same JVM passes.

      Thus, i think i'm having a lazy-loading issue: when i call getX server-side before sending the response to the client, it works because i have just forced the state to be reloaded by navigating the getX relation.
      When the test and JBPC are in the same JVM, the test passes because lazy-loading can work in this case (i'm not "detached" to use a Hibernate analogy)
      But when the test is remote AND i don't navigate the relation, i'm detached and lazy-loading can't work (unlike Hibernate i don't get LazyInitializationException though, i just silently get an incorrect state).

      So my question is:
      -is it a lazy-loading issue?
      -if so how do i specify to JBPC that i want eager-loading on serialization?