-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Error Using Ejb3Configuration to build multiple EMFs
PostPosted: Thu Dec 18, 2008 1:56 pm 
Newbie

Joined: Thu Dec 18, 2008 12:29 pm
Posts: 2
Hi guys,

I had created a factory class that use Ejb3Configuration to add the dynamic persistent-units.

Code:
public class JPAUtil
{
   private static Logger log = Logger.getLogger(JPAUtil.class);
   private static Map<String, EntityManagerFactory> factories = new HashMap<String, EntityManagerFactory>();
   private static final List<String> businessJars = Arrays.asList(
      "entity-impl-0.0.1.jar",
      "access-impl-0.0.1.jar");
   
   private static final List<String> dataSourceNames = Arrays.asList(
      "ums001DS", "ums002DS");
   
   public static void createEMFs()
   {
      for ( String dsName : dataSourceNames )
      {
         if ( !factories.containsKey(dsName) )
         {
            log.debug("EntitiManagerFactory does not exists.");
            createEMF(dsName);
         }
      }
   }
   
   private static void createEMF(String dataSourceName)
   {
      try
      {
         log.info("Creating new EntityManagerFactory to the DataSource "
               + dataSourceName);
         
         Ejb3Configuration ejbConf = new Ejb3Configuration();
         
         log.info("Setting the properties");
         
         ejbConf.setProperty("hibernate.connection.datasource", "java:/"
               + dataSourceName);
         ejbConf.setProperty("hibernate.dialect",
            "org.hibernate.dialect.PostgreSQLDialect");
         
         ejbConf.setProperty("hibernate.transaction.factory_class",
            "org.hibernate.transaction.JTATransactionFactory");
         /*
         ejbConf.setProperty("hibernate.transaction.manager_lookup_class",
            "org.hibernate.transaction.JBossTransactionManagerLookup");
         */
         ejbConf.setProperty("hibernate.show_sql", "false");
         ejbConf.setProperty("hibernate.format_sql", "true");
         
         ejbConf = mapJarsEntities(ejbConf);
         
         log.info("Building EntityManagerFactory");
         EntityManagerFactory emf = ejbConf.buildEntityManagerFactory();
         
         log.info("Adding EntityManagerFactory to the factories Map");
         factories.put(dataSourceName, emf);
      }
      catch ( Exception e )
      {
         log.error(e);
      }
   }
   
   private static Ejb3Configuration mapJarsEntities(Ejb3Configuration ejbConf)
   {
      for ( String nomeJar : businessJars )
      {
         mapEntityClasses(ejbConf, nomeJar);
      }
      
      return ejbConf;
   }
   
   
   @SuppressWarnings("unchecked")
   private static Ejb3Configuration mapEntityClasses(Ejb3Configuration ejbConf,
         String jarName)
   {
      try
      {
         Filter[] filters = new Filter[2];
         filters[0] = new PackageFilter(false, null)
         {
            public boolean accept(String javaElementName)
            {
               return true;
            }
         };
         filters[1] = new ClassFilter(false, new Class[] {
               Entity.class, MappedSuperclass.class, Embeddable.class })
         {
            public boolean accept(String javaElementName)
            {
               return true;
            }
         };
         log.info("processing jar " + jarName);
         JarVisitor j = JarVisitorFactory.getVisitor(Thread.currentThread()
            .getContextClassLoader().getResource(jarName), filters);
         Set<Entry>[] entries = (Set<Entry>[])
            j.getMatchingEntries();
         for ( int i = 0; i < entries.length; i++ )
         {
            for ( Entry c : entries[i] )
            {
               log.info("Entity Found: " + c.getName());
               ejbConf.addAnnotatedClass(Class.forName(c.getName()));
            }
         }
      }
      catch ( IOException e )
      {
         log.error(e);
      }
      catch ( ClassNotFoundException e )
      {
         log.error(e);
      }
      return ejbConf;
   }
   
   public static EntityManager getEntityManager(String dataSourceName)
   {
      EntityManager em = null;
      try
      {
         log.info("getting EntityManager to the DataSource "
               + dataSourceName);
         
         if ( !factories.containsKey(dataSourceName) )
         {
            log.debug("EntitiManagerFactory does not exists.");
            createEMF(dataSourceName);
         }
         
         log.debug("creating EntityManager");
         em = factories.get(dataSourceName).createEntityManager();
         
         log.debug("returning EntityManager");
      }
      catch ( Exception e )
      {
         log.error(e);
      }
      return em;
   }
}



I tried to test connecting to a DS db001ds and made a persist and a find operation successfully.

But when I try to create 2 EntityManagerFactory's, (DS db001ds and db002ds) i get the following warn:

Code:
...
14:09:45,953 INFO  [DatasourceConnectionProvider] Using datasource: java:/db002ds
14:09:45,984 WARN  [loggerI18N] [com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.dis
allow] [com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.disallo
w] Adding multiple last resources is disallowed. Current resource is org.jboss.resource.connectionma
nager.TxConnectionManager$LocalXAResource@1bc6b34
14:09:46,000 WARN  [SettingsFactory] Could not obtain connection metadata
org.jboss.util.NestedSQLException: Could not enlist in transaction on entering meta-aware object!; -
nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Una
bled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57ffbb:5b6:49492433:65 status: ActionStatus.ABORT_ONLY >); - nested throwable: (org.j
boss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!
; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable:
Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57ffbb:5b6:49492433:65 status: ActionStatus.ABORT_ONLY >))
        at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:95
)
...




And any subsequent call to the EntityManager of db002ds throws the same message, but now like error and not warn.

Someone had used Ejb3Configuration without trouble to connect in multiple persistent units?
Thanks for your time,

Jorge


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2008 6:08 pm 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
Construct the EMF's each in separate JTA transactions. The error you're seeing happens because you're trying to enlist multiple non-XA resources in a single JTA transaction.

This probably means that you need to lazily create EMF as they're accessed, not all at once up front.

That or just let the EJB3 deployer do its work and don't mess around with Ejb3Configuration....

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 05, 2009 2:23 pm 
Newbie

Joined: Thu Dec 18, 2008 12:29 pm
Posts: 2
Hi all


I found this page in the web: http://www.jboss.org/community/docs/DOC-11443.

So, I had added the property <property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true" /> in the jbossjta-properties.xml file, like said.

then I could create 2 databases and use them successfully, but now I got this warn when persisting an object:

Code:
10:33:09,953 WARN  [loggerI18N] [com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.multipleWarning] [com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.multipleWarning] Multiple last resources have been added to the current transaction. This is transactionally unsafe and should not be relied upon. Current resource is org.jboss.resource.connectionmanager.TxConnectionManager$LocalXAResource@5550c2


Is there any problem by using this solution?


thx for your time.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 05, 2009 2:26 pm 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
Allowing multiple last resources is generally a bad idea because 2-phase-commit cannot work properly. If the *only* time you see this error is during startup, then it is conceptually safe. But I stand by my prior advice as TheRightSolution.

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.