24

I would like to put some of the hibernate configuration in a property file to make it editable without build and deploy.

I tried to solve my problem by following the instructions from Create JPA EntityManager without persistence.xml configuration file

app.properties:

hibernate.show_sql=true 
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=validate 
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.default_schema=myschema

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Persistence deployment descriptor for dev profile -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
             version="1.0">

   <persistence-unit name="pu">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>jdbc/appDatasource</jta-data-source>
      <properties>
         <property name="jboss.entity.manager.factory.jndi.name" value="java:/appEntityManagerFactory"/>
      </properties>
   </persistence-unit>

</persistence>

In the initialization code the application executes the following sequence, (which finds the properties),

Properties props = new Properties();
InputStream is = ClassLoader.getSystemResourceAsStream( "app.properties" );
props.load( is );
Persistence.createEntityManagerFactory( "pu", props );

but fails with the error message:

 INFO  [SessionFactoryImpl] building session factory
 INFO  [SessionFactoryObjectFactory] Not binding factory to JNDI, no JNDI name configured
ERROR [STDERR] javax.persistence.PersistenceException: [PersistenceUnit: pu] Unable to build EntityManagerFactory

Does anyone have an idea what could be wrong with my configuration?

Versions: JBoss 4.3 Seam: 2.1.2

EDIT:

JBoss JNDI enlists "pu" as persistence unit:

persistence.units:ear=app.ear,jar=app.jar,unitName=pu (class: org.hibernate.impl.SessionFactoryImpl)
Community
  • 1
  • 1
stacker
  • 68,052
  • 28
  • 140
  • 210
  • @stacker Let me know: Have you deployed a datasource whose global jndi address is **jdbc/appDatasource** ??? – Arthur Ronald Oct 14 '10 at 18:30
  • @Arthur thanks for your response. Yes, I tried several JNDI names after the error occurred. I suppose it gets the persistenceUnits name "pu" wrong since it isn't complaining about the datasource. – stacker Oct 14 '10 at 19:41
  • @stacker I need additional info: post how your app is built ( As shown here: http://stackoverflow.com/questions/2453746/2459795#2459795 ) Try to use SeamTest (Take a look at Seam **examples** directory - There are a lot of tests). – Arthur Ronald Oct 14 '10 at 21:00
  • @stacker How to set up a connection pool in JBoss: **1°** Copy your database's JDBC JAR file to $JBOSS_HOME/server/default/lib **2°** JBoss includes example database connection-pool files in the directory $JBOSS_HOME/docs/examples/jca. **The name of each file ends in -ds.xml** For instance, oracle-ds.xml. Copy your Target database **-ds.xml** file to $JBOSS_HOME/service/default/deploy and set up your datasource As follows – Arthur Ronald Oct 14 '10 at 21:05
  • OracleDS jdbc:oracle:thin:@localhost:1521:app oracle.jdbc.driver.OracleDriver scott tiger – Arthur Ronald Oct 14 '10 at 21:07
  • For the example above, JBoss will create a global jndi datasource called **java:/OracleDS** – Arthur Ronald Oct 14 '10 at 21:09

5 Answers5

10

As an alternative to your current approach and since you're using Hibernate, you could use Hibernate to configure JPA by declaring a hibernate.cfg.xml file using the hibernate.ejb.cfgfile property, like this:

<persistence>
 <persistence-unit name="manager1" transaction-type="JTA">
    <jta-data-source>java:/DefaultDS</jta-data-source>
    <properties>
       <property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>
    </properties>
 </persistence-unit>
</persistence>

My understanding is that the hibernate.cfg.xml is just supposed to be on the classpath (so it could be outside the packaged archive).

References

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • Thank you Pascal, I will try that ASAP – stacker Oct 16 '10 at 19:47
  • 2
    And what's the solution for javax.persistence/EclipseLink? – Alex Feb 14 '12 at 18:20
  • I cannot archive this with hibernate 4.3.5. Many exceptions, e.g., java.lang.UnsupportedOperationException: The application must supply JDBC connections, Connection cannot be null when 'hibernate.dialect' not set occurred. Besides, I cannot find this property in the least hibernate document: http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/ I finally use the solution here: http://stackoverflow.com/questions/4548353/externalize-credentials-from-persistence-xml-in-j2se-app – petertc Jun 09 '14 at 15:09
3

Just found a an alleged way for EclipseLink users. There is "eclipselink.persistencexml" which has a default value of

public static final String ECLIPSELINK_PERSISTENCE_XML_DEFAULT = "META-INF/persistence.xml";

but it can't be overridden although the docs say it can be...

/**
 * The <code>"eclipselink.persistencexml"</code> property specifies the full
 * resource name to look for the persistence XML files in. If not specified
 * the default value defined by {@link #ECLIPSELINK_PERSISTENCE_XML_DEFAULT}
 * will be used.
 * <p>
 * IMPORTANT: For now this property is used for the canonical model
 * generator but it can later be used as a system property for customizing
 * weaving and application bootstrap usage.
 * <p>
 * This property is only used by EclipseLink when it is locating the
 * configuration file. When used within an EJB/Spring container in container
 * managed mode the locating and reading of this file is done by the
 * container and will not use this configuration.
 */
Alex
  • 8,245
  • 8
  • 46
  • 55
1

I used this mechanism, seems to work for most of the properties, had issues with non-jta-data-source.

http://www.eclipse.org/eclipselink/api/2.4/index.html?org/eclipse/persistence/config/PersistenceUnitProperties.html

1

If you are using Spring to manage and inject entity manager, then it is possible to implement org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor and pass on external properties. I could successfully externalize all properties from persistence.xml using this.

Rajesh
  • 419
  • 1
  • 6
  • 20
0
**persistence.xml**
            
            <?xml version="1.0" encoding="UTF-8"?>
            <persistence version="2.2"
                xmlns="http://xmlns.jcp.org/xml/ns/persistence"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
                <persistence-unit name="jsf-maven-project">
                    <properties>
                       <property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>
                    </properties>
                </persistence-unit>
            </persistence>
           
**hibernate.cfg.xml**
            <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
          <hibernate-configuration>
            <session-factory>
              <property name="connection.driver_class">org.postgresql.Driver</property>
              <property name="connection.url">jdbc:postgresql://localhost:5432/testdb</property>
              <property name="connection.username">postgres</property>
              <property name="connection.password">Test@123</property>
              <property name="connection.pool_size">10</property>
              <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
              <property name="current_session_context_class">thread</property>
              <property name="show_sql">true</property>
              <property name="format_sql">true</property>
              <property name="hbm2ddl.auto">update</property>
              <!-- mapping  class="com.sample.Book" / -->
          </session-factory>
        </hibernate-configuration>
    
**HibernateUtil.java**
            public static EntityManager getEntityManager() {
                    if (entityManagerFactory == null) {
                        entityManagerFactory = Persistence.createEntityManagerFactory("jsf-maven-project");
                    }
                    return entityManagerFactory.createEntityManager();
                }
            

I was createing JSF project with hibernate JPA and this solution worked for me.

Mayur Jain
  • 149
  • 5