5 Replies Latest reply on Mar 10, 2006 1:48 PM by zauberlehrling

    Transient members

    zauberlehrling

      Hello,

      I have a question concerning transient members. In the follwoing code there is an Entity Bean:

      package entities;
      
      import java.io.Serializable;
      import java.util.*;
      import javax.persistence.*;
      
      @Entity
      public class Node implements Serializable {
      
       private int id;
       private String persistentText;
       private String transientText;
      
       public Node(){}
      
       public Node(int id)
       {
       setId(id);
       }
      
       @Id
       public int getId() {
       return id;
       }
      
       public void setId(int id) {
       this.id = id;
       }
      
       public String getPersistentText() {
       return persistentText;
       }
      
       public void setPersistentText(String persistentText) {
       this.persistentText = persistentText;
       }
      
       @Transient
       public String getTransientText() {
       return transientText;
       }
      
       public void setTransientText(String transientText) {
       this.transientText = transientText;
       }
      }


      a Session Bean:

      package server.sessions;
      
      import javax.ejb.*;
      import javax.persistence.*;
      import org.hibernate.*;
      import entities.*;
      
      import java.util.*;
      
      @Stateful
      public class ClientSessionBean implements ClientSessionLocal, ClientSessionRemote{
      
       @PersistenceContext private EntityManager manager;
      
       List<Node> nodes;
       Node node;
      
       public void createNode()
       {
       node = new Node(1);
       node.setTransientText("transient");
       node.setPersistentText("persistent");
       manager.persist(node);
       nodes = manager.createQuery("from Node where id=1").getResultList();
       node = nodes.get(0);
       System.out.println("createNode persistentText: "+node.getPersistentText());
       System.out.println("createNode transientText: "+node.getTransientText());
       }
      
       public void showNode()
       {
       nodes = manager.createQuery("from Node where id=1").getResultList();
       node = nodes.get(0);
       System.out.println("showNode persistentText: "+node.getPersistentText());
       System.out.println("showNode transientText: "+node.getTransientText());
       }
      
      }
      


      and a client, which calls the two methods createNode() and showNode():

      package client;
      
      import javax.naming.InitialContext;
      import java.util.*;
      import entities.*;
      import server.sessions.*;
      
      public class Client {
      
       static ClientSession clientSession;
      
       public static void main(String[] args) {
       try {
       Hashtable<String,String> env = new Hashtable<String,String>();
       env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
       env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
       env.put("java.naming.provider.url", "localhost");
       InitialContext ctx = new InitialContext(env);
       clientSession = (ClientSession)ctx.lookup("ClientSessionBean/remote");
       clientSession.createNode();
       clientSession.showNode();
       }
       catch (Exception e)
       {
       System.out.println(e);
       }
       }
      }


      I get the following answer:
      ..
      10:59:02,531 INFO [STDOUT] createNode persistentText: persistent
      10:59:02,531 INFO [STDOUT] createNode transientText: transient
      10:59:02,562 INFO [STDOUT] showNode persistentText: persistent
      10:59:02,562 INFO [STDOUT] showNode transientText: null
      ..
      Is the last line correct? I've exptected the last line:

      10:59:02,562 INFO [STDOUT] showNode transientText: transient

      Thanks for your efforts.

        • 1. Re: Transient members
          mwoelke

          of course its correct.
          The spec says:

          9.1.14 Transient Annotation
          The Transient annotation is used to annotate a property or field of the entity class. It specifies that
          the property or field is not persistent.
          @Target({METHOD, FIELD}) @Retention(RUNTIME)
          public @interface Transient {}
          Example:
          @Entity
          public class Employee {
          @Id int id;
          @Transient User currentUser;
          ...
          }

          which means, that if u fetch a entity bean from the database, its transient members can not be initialized since they are not stored.

          regards, milan wölke

          • 2. Re: Transient members
            zauberlehrling

            Hello Milan,

            thanks for your answer.
            Do you know wether the entity bean is always fetched
            from the database or is it possible that the entity bean exist
            as an object in the java virtual machine? Of course changes
            to the persistent fields must be in sync with the database.

            Best Regards

            Frank

            • 3. Re: Transient members
              mwoelke

              U r referring to some kind of caching, dont u.
              Unfortunately a cache is not part of the ejb30 spec, but u can use the hibernate l2 cache. It keeps your entitybeans in memory, and keeps them in sync with the db. the drawback is, that u have to use hibernate annotations with your entity beans, which i personally dislike.

              --> hint: jboss-entity-cache

              dont ask me, is transient field would survive caching, u have to try that.

              but to answer the first question, if u dont use l2 caching, yes it will be fetched every time.

              • 4. Re: Transient members
                zauberlehrling

                Although the data is not persistent via the EJB3 persistence mechanism, I would like to keep some data in the entity beans.
                I will take a closer look at the the jboss-entity-cache!

                • 5. Re: Transient members
                  zauberlehrling

                  Hello Milan,

                  thank you for your hint. I switched on the EJB3EntityTreeCache and this cache works. One can check this via

                  jmx-console
                  -> service=EJB3EntityTreeCache
                  -> java.lang.String printDetails() invoke

                  But here is a catch in it! Only the data persistent via the hibernate mapping is cached. So this does not have the desired effect.

                  I'm trying now the following: I create a reference from the JNDI to this bean. If I access the field transientText in the Node-bean, then I get the originally value.