-->
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.  [ 8 posts ] 
Author Message
 Post subject: Persistence unit both in and out of the container
PostPosted: Tue Sep 12, 2006 5:54 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
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?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 12, 2006 9:38 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Why would you want to make an _environment dependent configuration file_ work in any environment? Just deploy a different persistence.xml file for each environment. Are you really surprised that a _configuration file_ only works for one _configuration_ and not the other?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 13, 2006 1:53 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
Who said anything about being surprised? :-)

If persistence.xml is really an environment dependant configuration file and you're supposed to use a different one based on where you're deploying it, then why does it go inside the jar or ear? Shouldn't it stay with the environment it is describing?

An alternate way of seeing it would be that the persistence.xml file is not an environment dependant configuration file. It instead defines the data connection requirements of the jar-ed up code. That's why it's in the jar. The container would then bind to that (using *-ds.xml which is defined in the app server) and when running out of container, you could define your connection parameters and pass them in as code.

That seems much more reasonable to me and was the way I was trying to make it work.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 16, 2006 8:22 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
OK, I still can't figure out how to get this to work short of making two different persistnece.xml files in 2 jars and packaging different ones based on if it's going into a J2EE ear or the JavaSE jar.

Is that what everyone is doing? I would still appreciate hearing from anyone who is using the same persistence jar inside and outside the container and what their persistnece.xml file(s) looks like and how they have it all packaged. Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 17, 2006 10:21 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
As Christian said, persistence.xml is a Deployment time file, Don't tell me you can't replace a file in a jar through a ant task.

Alternatively, use JBoss Embeddable to run a container in both SE and EE (basically being always in EE).

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 17, 2006 10:34 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
Yes of course I can do that... and that is what I've got coded up now. I am still interested in hearing from other people doing this. It does feel like an ugly hack to have my build.xml spit out two jars where the only difference is the persistence.xml that is packed inside.

The embedded JBoss is an interesting idea. I was mostly interested in this for running unit tests against the ejb3 jar and the thread-local pattern seemed like a good way to get it done. I will look into it.

Thanks for your work to get the entity manager and annotations packages and docs updated btw...


Top
 Profile  
 
 Post subject: Re: Persistence unit both in and out of the container
PostPosted: Mon Oct 12, 2009 8:31 am 
Newbie

Joined: Mon Oct 12, 2009 8:28 am
Posts: 2
What did you do for this in the end then?

I have exact the same issue..

I wonder if it's worth having two build targets just to swap the persistence.xml over....

Can't I just dynamically change it or something....


Top
 Profile  
 
 Post subject: Re: Persistence unit both in and out of the container
PostPosted: Sun Oct 18, 2009 7:02 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
you can change it "dynamically" only when creating the EntityManagerFactory yourself (programmatically), that way you can use a Java Properties object and use it to configure the EntityManager without using a persistence.xml file.
The whole point of having a persistence.xml is to avoid the need of rebuilding the application for a configuration change, so this is highly recommended.
Use Ant resource filtering to replace the tokens in the configuration file, or Maven2 also has resource filtering so you can have different deploy profiles (let's say dev, staging, production) producing different flavours of persistence.xml.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.