Hibernate version: 3.2.0.CR2
I had tried to get this working before
without much success. Now I'm trying a different approach. What I am trying to do is have the same persistence unit that works both in and out of container. In the book
Mastering EJB it says that provider is required in J2SE applications and therefore the simplest persistence.xml is this:
Code:
<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="DEV">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
In J2SE code I have the following:
Code:
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle9Dialect");
properties.put("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");
properties.put("hibernate.connection.username", "user");
properties.put("hibernate.connection.password", "pass");
properties.put("hibernate.connection.url", "jdbc:oracle:thin:@host:1521:tnsname");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.max_fetch_depth", "3");
properties.put("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
emf = Persistence.createEntityManagerFactory("DEV", properties);
In the jboss container we put a simple oracle-ds.xml definition:
Code:
<local-tx-datasource>
<jndi-name>DEV</jndi-name>
<connection-url>jdbc:oracle:thin:@host:1521:tnsname</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>user</user-name>
<password>pass</password> <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
This works well when running from a J2SE environment. Deploying this packaged as an ear in JBoss gives me the following:
Code:
java.lang.RuntimeException: You have not defined a jta-data-source for a JTA enabled persistence context named: DEV
at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:244)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
...
This seems wrong... this persistence unit is not JTA defined. OK, so lets try adding a JNDI name that can be used by JBoss:
Code:
<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="DEV">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DEV</jta-data-source>
</persistence-unit>
So in theory, JBoss will now bind the DEV datasource located by JNDI to the persistence unit. The
hibernate docs state that "When running without a JNDI available Datasource, you must specify JDBC connections with Hibernate specific properties." I am doing that in the J2SE version above by passing in a property so I thought I would be good. Sure enough, this makes JBoss happy but now the J2SE version fails with this:
Code:
17:38:27,562 FATAL DatasourceConnectionProvider:55 - Could not find datasource: java:/DEV
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.lookup(Unknown Source)
at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:61)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1928)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1211)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:631)
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:760)
at org.hibernate.ejb.Ejb3Configuration.createFactory(Ejb3Configuration.java:151)
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:205)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:114)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:37)
Does anyone have any ideas about how to either make Jboss ignore a J2SE persistence unit or perhaps how to specify the binding in JBoss config instead of the persistence.xml? More generally, how are the rest of you packaging/deploying your applications in and out of container such that this isn't a problem?