1 Reply Latest reply on Apr 23, 2008 9:26 AM by deanouk

    Scoping persistence units and dynamic lookups

    apill

      Here are my questions. These are repeated at the end of the post which fully explains my scenario. Any help would be helpful.

      1. Can I bind a persistence unit to JNDI name in a way that it is scoped within an ear?
      2. Or, can I look up the persistence unit name (<persistence-unit name="MapicsEM">) specified in the persistence.xml from within a session bean dynamically at runtime?


      I have the following deployment of 2 ears simmultaneously running in the same jboss server.

      app-1.ear
       |-------------my-ejbs-1.1.jar
       |-------------------META-INF/persistence.xml
      
      
      app-2.ear
       |-------------my-ejbs-1.2.jar
       |-------------------META-INF/persistence.xml
      


      My persistence.xml in both ejb jars are identical:
      <?xml version="1.0" encoding="UTF-8"?>
      <persistence>
       <persistence-unit name="MapicsEM">
       <jta-data-source>java:/MapicsDS</jta-data-source>
       <properties>
       <property name="hibernate.hbm2ddl.auto" value="none"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.DB2400Dialect" />
       <property name="hibernate.show_sql" value="false" />
       <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
       <property name="hibernate.cache.use_query_cache" value="true" />
       <property name="hibernate.ejb.cfgfile" value="mapics-hibernate.cfg.xml"/>
       </properties>
       </persistence-unit>
       <persistence-unit name="MapicsEM-US">
       <jta-data-source>java:/MapicsDS-US</jta-data-source>
       <properties>
       <property name="hibernate.hbm2ddl.auto" value="none"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.DB2400Dialect" />
       <property name="hibernate.show_sql" value="false" />
       <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
       <property name="hibernate.cache.use_query_cache" value="true" />
       <property name="hibernate.ejb.cfgfile" value="mapics-hibernate.cfg.xml"/>
       </properties>
       </persistence-unit>
      </persistence>
      


      The scenario is that app1.ear contains an older version (1.1) of the persistence archive than the persistence archive in app2.ear which uses version (1.2). Both versions have the same persistence.xml that refers to persistence units named MapicsEM and MapicsEM-US. If these were to conflict app2.ear's ejb classes would get hold of the wrong MapicsEM or MapicsEM-US and the entity classes would be incompatible with the ejb session bean code.

      According to the spec, by specifying my persistence.xml inside my ejb jar it is scoped to the ejb jar only. This works fine if my EJB injects the entity manager as follows:

      @PersistenceContext(unitName="MapicsEM")
      private Session session;
      


      Our company has multiple similar databases around the globe, for example one in the UK and one in the US. I could in my EJB session bean inject a persistence context for each database and use the appropriate session as required, for example

      @Stateless
      public class MyBean
      {
       @PersistenceContext(unitName="MapicsEM")
       private Session ukSession;
      
       @PersistenceContext(unitName="MapicsEM-US")
       private Session usSession;
      
      }
      


      However, if I need to add new databases I will keep needing to add more injected sessions.

      So, to resolve my problem, I would like my ejb to dynamically lookup my persistence contexts at runtime. I know this is possible with JNDI by specifying the following line in my persistence.xml and using InitialContext to look the jndi name up.

       <property name="jboss.entity.manager.jndi.name" value="java:/MapicsEM"/>
      


      However if I implement this in my scenario above, where I deploy 2 ears to jboss, both ears would try and bind MapicsEM to the same jndi name java:/MapicsEM and it will fail with NameAlreadyBoundException (or similar).


      Therefore my quesions are:

      1. Can I bind my persistence unit to JNDI in a way that it is scoped within the ear?
      2. Or, can I look up the persistence unit name (<persistence-unit name="MapicsEM">) specified in the persistence.xml at runtime that is already scoped to the ear?


      I did read something about ENC in J2EE where EJBs get a java:/comp/env context. Is it possible to bind my entity manager to this in some way?