1 2 Previous Next 15 Replies Latest reply on Dec 18, 2006 10:55 AM by konstantin.ermakov

    EntityManager is loosing updates

    konstantin.ermakov

      Hello!

      I have the following problem. In our project we are using the standart design - there is one EntityBean pojo per table, and one Stateless session bean which is working with the table. We are also using rich clients, which are manipulating the data, i.e.:

      
      @Entity
      public class SomeObject {
      
      private Integer id_;
      
      private String name_;
      
      @Id
      public void setId( Integer id ) {
       id_ = id;
      }
      
      public Integer getId() {
      return id_;
      }
      .....
      
      };
      
      
      @Stateless
      public class SomeStatelessBean {
      
       @PersistenceContext(name = "myname", unitName = "myunit")
       private EntityManager manager;
      
      
       public SomeObject getObject() {
       return manager.find(SomeObject.class, id);
       };
      
       public update( SomeObject detached ) {
       SomeObject obj = manager.find(detached.id);
       obj.setName( detached.getName );
       manager.flush();
       };
      
      };
      


      In the background there is a Timer Bean which is reading SomeObject information ( it does not manipulate, just reading ).

      The problem is as following. If I am calling update() very often my EntityManger returns me the old with the getObject() method object, though I am sure that the new copy is in database (Oracle). Can somebody tell me why does it happen?

      There are no exceptions on the server side, just the data is wrong.

      Thank you,
      Sincerely yours, Konstantin

        • 1. Re: EntityManager is loosing updates
          gnulp

          use the versioning-mechanism of the entity-manager - I think you will see some exceptions then ...

          
           java.lang.Long version;
          
           /**
           * Get the version property.
           *
           * @return java.lang.Long The value of version
           */
           @javax.persistence.Version
           public java.lang.Long getVersion()
           {
           return this.data.version;
           }
          
          
           ....
          
          




          • 2. Re: EntityManager is loosing updates
            konstantin.ermakov

            I added Version to my data and I did not receive any new exceptions. The only exception I can see in the JBoss log file is as following:

            2006-12-05 11:18:36,674 DEBUG [org.jboss.mq.il.uil2.ServerSocketManagerHandler] Exiting on IOE
            java.net.SocketException: socket closed
            at java.net.SocketInputStream.socketRead0(Native Method)
            at java.net.SocketInputStream.read(SocketInputStream.java:129)
            at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
            at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
            at org.jboss.util.stream.NotifyingBufferedInputStream.read(NotifyingBufferedInputStream.java:79)
            at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2205)
            at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2385)
            at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2452)
            at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2524)
            at java.io.ObjectInputStream$BlockDataInputStream.readByte(ObjectInputStream.java:2673)
            at java.io.ObjectInputStream.readByte(ObjectInputStream.java:874)
            at org.jboss.mq.il.uil2.SocketManager$ReadTask.run(SocketManager.java:317)
            at java.lang.Thread.run(Thread.java:595)

            And I do not think, that it is somehow connected to the problem. Did anyone met this problem before?

            • 3. Re: EntityManager is loosing updates
              konstantin.ermakov

              Before this exception I receive the following message:

              [org.hibernate.jdbc.JDBCContext] TransactionFactory reported no active transaction; Synchronization not registered

              • 4. Re: EntityManager is loosing updates
                konstantin.ermakov

                Hello!

                It seems that some internal error leads to incorrect data in my entity bean POJO:

                2006-12-05 14:13:14,496 INFO [myapp] Invoking: mypackage..session.MyObjectSession.getObject()
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.impl.SessionImpl] opened session at timestamp: 4773168719855617
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.jdbc.JDBCContext] TransactionFactory reported no active transaction; Synchronization not registered
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.jdbc.JDBCContext] successfully registered Synchronization
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Transaction already joined
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 1)
                2006-12-05 14:13:14,496 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
                2006-12-05 14:13:14,496 DEBUG [org.jboss.mq.il.uil2.SocketManager] End ReadTask.run
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.SQL]
                 /* select
                 x
                 from
                 MyObject x
                 where
                 x.id = 1 */ select
                 MyObject0_.ID as
                 .......
                 from
                 MyObject_DATA MyObject0_
                 where
                 MyObject0_.ID=1
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.SocketManager] End WriteTask.run
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.ServerSocketManagerHandler] Exiting on IOE
                java.net.SocketException: socket closed
                 at java.net.SocketInputStream.socketRead0(Native Method)
                 at java.net.SocketInputStream.read(SocketInputStream.java:129)
                 at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
                 at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
                 at org.jboss.util.stream.NotifyingBufferedInputStream.read(NotifyingBufferedInputStream.java:79)
                 at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2205)
                 at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2385)
                 at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2452)
                 at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2524)
                 at java.io.ObjectInputStream$BlockDataInputStream.readByte(ObjectInputStream.java:2673)
                 at java.io.ObjectInputStream.readByte(ObjectInputStream.java:874)
                 at org.jboss.mq.il.uil2.SocketManager$ReadTask.run(SocketManager.java:317)
                 at java.lang.Thread.run(Thread.java:595)
                2006-12-05 14:13:14,512 INFO [STDOUT] Hibernate:
                 /* select
                 x
                 from
                 MyObject x
                 where
                 x.id = 1 */ select
                 MyObject0_.ID
                 .....
                 from
                 MyObject_DATA MyObject0_
                 where
                 MyObject0_.ID=1
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.SocketManager] End ReadTask.run
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.SocketManager] Failed to handle: org.jboss.mq.il.uil2.msgs.CloseMsg18880098[msgType: m_connectionClosing, msgID: -2147480999, error: null]
                java.io.IOException: Client is not connected
                 at org.jboss.mq.il.uil2.SocketManager.internalSendMessage(SocketManager.java:265)
                 at org.jboss.mq.il.uil2.SocketManager.sendReply(SocketManager.java:239)
                 at org.jboss.mq.il.uil2.ServerSocketManagerHandler.handleMsg(ServerSocketManagerHandler.java:128)
                 at org.jboss.mq.il.uil2.SocketManager$ReadTask.handleMsg(SocketManager.java:396)
                 at org.jboss.mq.il.uil2.msgs.BaseMsg.run(BaseMsg.java:392)
                 at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:748)
                 at java.lang.Thread.run(Thread.java:595)
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.SQL]
                 /* select
                 x
                 from
                 MyObject x
                 where
                 x.id = 1 */ select
                 MyObject0_.ID as
                 .....
                 from
                 MyObject_DATA MyObject0_
                 where
                 MyObject0_.ID=1
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.UILClientILService] Stopping
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.SocketManager] End WriteTask.run
                2006-12-05 14:13:14,512 DEBUG [org.jboss.mq.il.uil2.SocketManager] Failed to send error reply
                java.io.IOException: Client is not connected
                 at org.jboss.mq.il.uil2.SocketManager.internalSendMessage(SocketManager.java:265)
                 at org.jboss.mq.il.uil2.SocketManager.access$800(SocketManager.java:52)
                 at org.jboss.mq.il.uil2.SocketManager$ReadTask.handleMsg(SocketManager.java:409)
                 at org.jboss.mq.il.uil2.msgs.BaseMsg.run(BaseMsg.java:392)
                 at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:748)
                 at java.lang.Thread.run(Thread.java:595)
                2006-12-05 14:13:14,512 INFO [STDOUT] Hibernate:
                 /* select
                 x
                 from
                 MyObject x
                 where
                 x.id = 1 */ select
                 MyObject0_.ID
                 ....
                 from
                 MyObject_DATA MyObject0_
                 where
                 MyObject0_.ID=1
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[mypackage..entity.MyObject#1]
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 2)
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 1) (open ResultSets: 0, globally: 0)]
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.engine.TwoPhaseLoad] resolving associations for [mypackage..entity.MyObject#1]
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.engine.TwoPhaseLoad] done materializing entity [mypackage..entity.MyObject#1]
                2006-12-05 14:13:14,512 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
                2006-12-05 14:13:14,512 INFO [myapp] MyObject name 3
                


                • 5. Re: EntityManager is loosing updates
                  gnulp

                  what database are you using ?
                  are transactions enabled ?
                  do you have rebuild the database using also the version in the database ?

                  ...

                  • 6. Re: EntityManager is loosing updates
                    konstantin.ermakov

                    Hi!

                    We are using Oracle 10g, it is the XA datasource. JBoss version is 4.0.4 GA.

                    For the version information I just added the column in my table, so I did not have to rebuild it.

                    • 7. Re: EntityManager is loosing updates
                      konstantin.ermakov

                      Sorry - there is no transaction management in this case.

                      • 8. Re: EntityManager is loosing updates
                        gnulp

                        I think you are "loosing updates" because you trigger several stateless session-beans in parallel (very often and fast) ...

                        So you have concurrent access to your data --> I was assuming, that you will get an exception telling you that you have the wrong version to update the object - unfortunatelly I don't know what's going on with your exception that you got.

                        I know it works, because we have also concurrent calls - and we get nice exceptions in case of two "threads" are manipulating the data ...

                        ...

                        • 9. Re: EntityManager is loosing updates
                          konstantin.ermakov

                          Hi!

                          I am tracing my flush() statement, and I am sure that is happens before I am trying to read the data.

                          If I understand it correctly, flush() is commiting the data and with the next manager.createQuery run the new data should be available.

                          Is it true, or flush() is doing some background work?

                          • 10. Re: EntityManager is loosing updates
                            gnulp

                            sorry - i haven't answered earlier ...

                            no - flush is NOT committing your transaction ! Your transaction is finished after you are leaving the SLSB --> when leaving the SLSB the container is running through several "intercepors" and is finishing the transaction - in other words it commits the changed data into the database !!! Before that - no other call can see the modified data (except you change the default behaviour of the container which is usually "read-commited") !

                            So if another thread of your frontend starts a second SLSB trying to modify the same entity it will still see the OLD data as long as the other call is not committed ! Thats why I asked you to "synchronize" your calls with the introduction of "version" which uses optimistic locking !!! You should get an exception in one of both transactions but not yours ;-)

                            hope I could help you ...



                            • 11. Re: EntityManager is loosing updates
                              konstantin.ermakov

                              Hi!

                              Thanks a lot for your answer. I actually want not to update the entity from the second thread, but just be sure, that the entity I am reading is up-to-date. And, of course, @Version, optimistic locking does not help me in this case. In general, let's assume the following scenario.


                              * In some stateless bean we have the update() method:
                               ...
                               void update() {
                               .....
                               entity.setName("Name");
                               manager.flush();
                               sendJMSNotification();
                               };
                              

                              * sendJMSNotification() is sending a message to the rich clients, that the entity was updated (in my case, the interceptor is doing it)
                              * the client is trying to call manager.find(...) from the same stateless bean, and receives an old data.


                              So, the main question is , if there is a possibility to get postCommit event? IMHO this is important, because the client may receive the notification and in theory, the client does NOT have to access the EJB server, but the database directly. The good example would be a reporting tool, which is refreshing the data after receiving the notification.

                              Even If I am implementing manager.lock( entity, LockType.READ ), I think it does not work properly in this case - after flush() method the lock is gone.

                              The only workaround I see is to use the direct JDBC calls, but then it does not make sence to use EJB and Persistence API to work with database.

                              • 12. Re: EntityManager is loosing updates
                                konstantin.ermakov

                                In addition to, I have the following question. If I am calling my update() method from the client, may I be sure that after this call from the same client from the same thread I will NOT receive the old data?

                                • 13. Re: EntityManager is loosing updates
                                  dilator

                                  Hibernate provides both Interceptors and Event listeners - they should do the trick, as long as you dont mind using non-JPA features

                                  • 14. Re: EntityManager is loosing updates
                                    konstantin.ermakov

                                     

                                    "dilator" wrote:
                                    Hibernate provides both Interceptors and Event listeners - they should do the trick, as long as you dont mind using non-JPA features

                                    I was trying to use @PostUpdate event listener - it does not help.

                                    1 2 Previous Next