9 Replies Latest reply on Dec 10, 2009 7:21 PM by Dave Chen

    how to create PersistenceUnit and map to dataSource programm

    Dave Chen Master

      Hi, Currently we use the persistence.xml to map a persistenceUnit to data source. Our application got a requirement:

      create a new persistence unit programmatically and map it to a new datasource without redeploy or server restart. How to achieve this functionality?

      What is the maximum number of persistence units and data sources that one Jboss AS can manage? Is there a limit?

      Any help would be helpful.

      Thanks.
      Dave

        • 1. Re: how to create PersistenceUnit and map to dataSource prog
          Jose Antonio Newbie

          The only solution that I've found is to create the Entity Managers (and factories) through the Persistence.createEntityManagerFactory method passing it a Map with the JNDI direction of the new datasource. You can also pass the datasource connection information by hibernate properties in the same map.

          See:
          http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html

          In the section 2.2.2

          • 2. Re: how to create PersistenceUnit and map to dataSource prog
            Dave Chen Master

            Thanks for help.

            Is the persistence unit name required to be defined in a persistence.xml?

            what is the property name for data source in the map?

            Thanks!
            Dave

            • 3. Re: how to create PersistenceUnit and map to dataSource prog
              Jose Antonio Newbie

              I have the same problem as you. I need to use different databases with the same tables in the same application (the difference is that for me is that redeploying or even restarting JBoss is permitted, but in this case, it doesn't matter).

              The idea is to use the same persistence unit changing only the datasource that they use, so the name of the persistence unit can be the same (I think, somebody correct me if I'm wrong). The name has to be defined in persistence.xml because it's mandatory in JPA as well as a default datasource. Then, you can use the Persistence.createEntityManagerFactory method passing it:

              - The name of the unit that you gave in persistence.xml
              - javax.persistence.jtaDataSource or javax.persistence.nonJtaDataSource properties pointing to the JNDI address of the datasource that you want to use, previously configured with access to your database. The case here (and the problem for me) is that I cannot use a JTA datasource, so I don't know why the property is there.

              Anyway. I havent's tested it deeply but in theory, this should work.

              • 4. Re: how to create PersistenceUnit and map to dataSource prog
                Dave Chen Master

                Thanks for help.

                If one peristence unit is mapped to many data sources(with same tables), is there any problems with Hibernate caching?

                We tried the following in a stateless session bean:

                Map configOverrides = new HashMap();
                EntityManagerFacotry emf = Persistence.createEntityManagerFactory("unit1", configOverrides);

                But got exception:

                javax.persistence.PersistenceException: [PersistenceUnit: unit1] Unable to build EntityManagerFactory


                <persistence-unit name="unit1">
                 <jta-data-source>java:/dataSource1</jta-data-source>
                
                 <properties>
                 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
                 <property name="hibernate.hbm2ddl.auto" value="update"/>
                 <property name="hibernate.show_sql" value="false"/>
                 </properties>
                 </persistence-unit>


                But the following works.

                @PersistenceContext (unitName="unit1")
                protected EntityManager em;


                What is the right way to create entityManagerFactory? Thanks!
                Dave

                • 5. Re: how to create PersistenceUnit and map to dataSource prog
                  Dave Chen Master

                  From debugging, the issue seems to be in method:

                  PersistenceUnitDeployment.start();

                  which is in the jar "jboss-jpa-deployer.jar".

                  Where can I find the source code for the jar? I could not find it under
                  http://anonsvn.jboss.org/repos/

                  Thanks!

                  • 6. Re: how to create PersistenceUnit and map to dataSource prog
                    Dave Chen Master

                    the previous message is for deploy phase. I was wrong. From further debug, the exception is thrown in SessionFactoryImp.java

                    throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");

                    if ( settings.getTransactionManagerLookup()!=null ) {
                     log.debug("obtaining JTA TransactionManager");
                     transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
                    }
                    else {
                     if ( settings.getTransactionFactory().isTransactionManagerRequired() ) { throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");
                     }
                     transactionManager = null;
                    }


                    How to fix it? It seems a configuration issue. Thanks!
                    JBoss: 5.1.0GA.

                    • 7. Re: how to create PersistenceUnit and map to dataSource prog
                      Jose Antonio Newbie

                      Unfortunately, you cannot use a JTA datasource unless you get the entity managers by injection, so you cannot use the jta-data-source element and you have to set the javax.persistence.nonJtaDataSource property in the map.

                      Also, if you are using EJBs, you have to add the @TransactionManagement(TransactionManagementType.BEAN) annotation to the Bean to disable JTA.

                      • 8. Re: how to create PersistenceUnit and map to dataSource prog
                        Dave Chen Master

                        Why is there such limitation? From programming API, it just overrides the property declared in persistence.xml. For BEAN management type, do we need to implement any transation related methods? We use JBoss 5.1.0 GA.

                        Thanks for help.

                        • 9. Re: how to create PersistenceUnit and map to dataSource prog
                          Dave Chen Master

                          We tried, but got exception:

                          08:17:58,204 ERROR [STDERR] javax.persistence.PersistenceException: [PersistenceUnit: defaultDataSource] Unable to build EntityManagerFactory
                          08:17:58,205 ERROR [STDERR] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
                          08:17:58,205 ERROR [STDERR] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
                          08:17:58,205 ERROR [STDERR] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)