7 Replies Latest reply on Nov 2, 2009 2:25 AM by Nikolay Elenkov

    reading entities in transaction

    Sascha Effert Newbie

      Hello,


      I have tried following with SEAM 2.0 on JBoss 4.2.3, 5.0 and 5.1 and with SEAM 2.2 on JBoss 5.1 (it was the reason for updating my project:


      In a transaction I update some of my Entites by changing CMRs. If I fetch the entities again from the DB I get the outdated values. E.G. I have a EntityClass Process holding references to the father process and to all child processes I would do it as followed:


      @Entity
      public class Process {
      
        @Id
        Long id;
      
        [...]
        @ManyToOne
        private Process father;
      
        @OneToMany(mappedBy = "father")
        private List<Person> children;
       
        [...]
      }
      



      Now I do the following in a Transaction:


      @Transactional
      public void foo {
        Process father = entityManager.createQuery(from Process where id=25").getSingleResult();
        Process child = new Process();
        child.setFather (father);
        EntityManager.persist(child);
        [...]
        Process father2 = entityManager.createQuery(from Process where id=25").getSingleResult();
        for (Process fChild : father2.getChildren()) {
          log.info("Child: #0", fChild.getId());
        }
      }
      



      I do not get the newly added child. I use seam managed persistence and I get the EntityManager injected using @In. Where is my fault? Am I right here or should I ask in the hibernate mailing list?


      bests


      Sascha Effert
       

        • 1. Re: reading entities in transaction
          Nikolay Elenkov Master

          Since you are not touching the father entity, you are getting a cached instance from the EM. If you clear the EM, before the second query you should get the entity from DB. Other than that, if it is a bidirectional association, you need to update both sides, i.e.:


          child.setFather(father);
          father.getChildren().add(child);
          



          And, yes, this is a Hibernate question :)


          • 2. Re: reading entities in transaction
            Sascha Effert Newbie

            Sorry, I have been out of office for the last two days.


            You are right, adding it at both sides helped. It would be much nicer for if I could disable the Caching at that moment (or for the whole application or the whole application server). I will search at hibernate how to do that...


            Thank you very much.


            bests


            Sascha Effert

            • 3. Re: reading entities in transaction
              Nikolay Elenkov Master

              If you are using Hiberante (or JPA), entities will be cached by the persistence context, that's just how it works. You can clear the cache (EntityManager.clear(), but that clears everything, so make sure it doesn't influence other parts of your application. Is you use Hibernate, you can use evict to remove a single entity from the cache. Disabling it altogether is possible, but you should really be sure that's what you want to do.

              • 4. Re: reading entities in transaction
                Sascha Effert Newbie

                I think I would at least want to try what happens after disabling the Cache. In fact my application is only in small area performance relevant, in all other areas it is no problem if the application needs some time. But until now I am also quite happy by adding CMRs on both sides... What I would like most would be to diable caching for single transactions.

                • 5. Re: reading entities in transaction
                  Jean Luc Apprentice

                  You're trying to go against one of the major design goals of a persistence context. PC-level caching is not there only for performance, but also to ensure database identity (to only have one object instance representing a row in a given PC).

                  • 6. Re: reading entities in transaction
                    Sascha Effert Newbie

                    Hmmm... if different parts of my application in different transaction use the same entity, they are working on the same object? Are you really sure? I thought the integrity is given by the database. So I could not have an entity in different states in different transactions... This would make transactions senseless...

                    • 7. Re: reading entities in transaction
                      Nikolay Elenkov Master

                      What exactly do you mean by 'transaction'?


                      A persistence context may be bound to the conversation (SMPC, @In EntityManager), in this case you will have one entity managed by the PC for the duration of the conversation. Your PC will be used in many database transactions. If you use EJB's and a transaction-scoped PC (@PersistenceContext EntityManager), you will get a fresh (no cache) PC for every new database transaction you (or Seam) starts. Consider what your use case is and choose one or the other. If you don't want/need second level caching at all, better use plain old SQL (maybe with Spring's JDBC template). If you go with JPA/Hibernate, get a good book on that.


                      HTH