OpenJPA > Is it possible to define persistence xml file somewhere else than META-INF with name persistence.xml - openjpa

I am a new OpenJPA 2.2.2 user. I noticed that the database configuration has to be defined in META-INF/persistence.xml. This sounds to be too inflexible. Moreover, I found from the OpenJPA 2.2.2 documentation:
The OpenJPA runtime includes a comprehensive system of configuration defaults and overrides:
OpenJPA first looks for an optional openjpa.xml resource. OpenJPA searches for this resource in each top-level directory of your CLASSPATH. OpenJPA will also find the resource if you place it within a META-INF directory in any top-level directory of the CLASSPATH. The openjpa.xml resource contains property settings in JPA's XML format.
You can customize the name or location of the above resource by specifying the correct resource path in the openjpa.properties System property.
On base the introduction above, it seems that the database configuration file name is only possible to be persistence.xml. Moreover, I tried to place it in the top-level directory of my CLASSPATH, i.e., not inside the META-INF directory, it didn't work at all! Is there is any way to define this database persistence xml more flexibly, say in somewhere else than META-INF and with other name than persistence.xml?

First, there is no replacement for persistence.xml (p.xml for short). This is needed no matter what. Furthermore, the location of this file is clearly defined in the JPA specification (e.g. see "8.2 Persistence Unit Packaging" in JPA 2.0 spec). You MUST follow those rules on packaging. OpenJPA first and foremost follows the rules of the spec in regards to this file and its settings. No JPA provider is going to ignore the rules w.r.t p.xml file.
The section of text you copy/pasted is from here in the OpenJPA documentation:
http://openjpa.apache.org/builds/2.2.2/apache-openjpa/docs/manual#ref_guide_conf_specify
As you can see, this section describes an optional file named openjpa.xml. This file does not replace a p.xml file! It adds to it. And as the documentation states, it is simply used to add properties. That is, you can not define your persistence unit here, the only thing you can define are properties (i.e. ). If you define a persistence unit here, it will not be used. As an example, lets look at this openjpa.xml file:
<?xml version="1.0"?>
<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="">
<properties>
<property name="openjpa.jdbc.Schema" value="MySchema" />
<property name="openjpa.jdbc.DBDictionary" value="db2" />
</properties>
</persistence-unit>
This file defines two properties. Notice that the persistence-unit name is blank. That is intentional because, as I mentioned above, we can't define a persistence unit in this file. Finally, you can place this file in the META-INF on your classpath, as mentioned in the documentation. If you put this at the same spot as your p.xml file it will be found. As an example, in my JSE JUnit test, I place it on my hard drive in the directory e:/openjpaConfig/META-INF/openjpa.xml. I then put a classpath entry in my JUnit test to point to the directory e:/openjpaConfig. The classpath could point to a jar which contains this file in its META-INF directory. In a Java EE environment, you could place the file in a .jar file and place the .jar file in the lib directory of an ear.

Related

Can I have two persistence.xml files in my spring maven project

Is it possible for me to have two different persistence.xml files under META-INF eg. persistence-one.xml and persistence-two.xml and then somehow use <property name="persistenceXmlLocation" value="${db.persistence.file.name}"/> in my spring-context.xml to use the appropriate one using property files ?
I am doing this because I have two separate environments with different configurations - providers/dialects etc.
If I do above changes then I get Caused by: java.io.FileNotFoundException: and it's not able to read the appropriate file.
How I can make this work ?
Spring 3, Hibernate 5.3
Whoaa... spring 3 with hibernate 5 is going to be... challenging.
In any case, I'd try using <property name="persistenceProvider" value="org.hibernate.jpa.HibernatePersistenceProvider" /> instead of jpaVendorAdapter.
You might want to take a look at the bean's javadoc to see which other properties might be relevant (alternatively, you can use the persistenceXmlLocation property and load all the properties from either persistence_dev.xml or persistence_prod.xml)

what are the possible locations of persistence.xml file in a web archive in jpa and how to specify that location for getting EntityManagerFactory?

**EntityManagerFactory factory=Persistence.getEnityManagerFactory(???);**
In specification they are explained in the context of EJBs.But i am not understanding the actual possible locations of persistence.xml in a web archive.
The persistence.xml must always be in the META-INF directory on the classpath. Normally it will be inside a jar that is on the classpath, such as a jar in /WEB-INF/lib/ in your war file.

Change web.xml after deployment

Is it advisable to change web.xml (or, in fact, any other file) in app server after the deployment? Do ALL app servers expose their deployment/directory structure?
I would prefer making changes locally, re-building the war (or .ear, etc.), and re-deploying the application.
Regarding your first question, it depends on the type of the resource. For a classpath resource, you can override the file in any directory that has a higher priority in the class loading mechanism of your application server ($CATALINA_HOME/lib for instance if you're using Tomcat). For an xml file, like web.xml, you can declare an external entity in the packaged file with an absolute path, but you have to be sure that the file will be present on the target server. For instance, your packaged web.xml could look like that:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document [
<!ENTITY webEntity SYSTEM 'C:\Temp\web.xml'>
]>
&webEntity;
So the actual content of the web.xml would be the content of the file C:\Temp\web.xml.
In short, there is no official way to do it but there are tricks. I guess, what people do is to produce a custom package for each production site. There are multiple ways to automate this with Maven like war overlay or classifiers. Here is an interesting link.
Regarding your second question, I would not rely on this assumption. It's quite straight-forward to modify an exploded resource on a Tomcat server but it's is not that simple on a JBoss AS.

JEE6 war packing into several modules

I want to split parts of my WAR application into different JAR components.
Every JAR component contains JPA-Entities, EJBs & JSF-Composite-Components.
Example: extracting the user management (XHTMLs, EJBs, JPA-Entities) into an own jar.
At first everything looks working fine as long as I don't have to use an entityManager.
Problem:
In EJBs of JAR-files the entityManager will never be injected.
I'm using the #PersistenceContext annotation for injection.
I have a beans.xml in all META-INF folders and everything (excepted entityManager) is injected correctly. It doesn't even matter if I place a persistence.xml in all JAR-files or only in the WAR-file.
Does anybody have a glue how this can be done?
Where do I have to place the different configuration files (beans.xml, persistence.xml)?
Do I need an ejb-jar.xml file?
Is this possible at all?
Technology-Stack:
JBoss 6.1 / PrimeFaces 3.2 / Maven / EJB 3.1 / Hibernate / JTA / CDI
You need a persistence.xml file in every jar that contains entities.
Every such persistence xml should define a different persistence unit.
If you want one persistence unit to refer to entities define in a different persistence unit then you need to include it as jar-file entry in the persistence unit definition (see example below).
This works for us for a very similar stack JBoss 5.1 (and then 7)/ EJB3/ Hibernate, Maven, ...
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="PersistenceUnitA">
<jar-file>JarContainingOtherPersistenceUnit</jar-file>
<jta-data-source>java:/jboss-mysql-ds</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</properties>
</persistence-unit>

How to store persistence.xml with other configuration files

I'm using EclipseLink as my JPA implementation. Our project has a directory where we keep all of our config files, and I would like to store my persistence.xml file in the config directory, but cannot find any way to tell createEntityManagerFactory to look there to find the persistence-unit.
It doesn't answer your question directly, but if you want to do it in order to externalize configuration of the application, I think the best approach would be to extract all configurable properties (such as connection settings, etc) into a separate properties file and pass them to createEntityManagerFactory() as a Map (also note that you can override properties from persistence.xml this way).
Then your persistence.xml will contain only non-configurable settings (such as a list of persistent classes, etc), i. e. it won't make sense to change these properties without rebuilding the whole application, and you can leave it in its default location.
You can achieve this by using spring-orm LocalContainerEntityManagerFactory (you don't need to use all the spring context stuff if you don't want to).
LocalContainerEntityManagerFactory lcemf = new LocalContainerEntityManagerFactory ();
lcemf.setPersistenceUnitName("some_pu");
lcemf.setpersistenceXmlLocation("file:/data/config.xml");
EntityManagerFactory emf = lcemf.createNativeEntityManagerFactory();
you can also ignore the xml once and for all, and configure all in code by using the LocalContainerEntityManagerFactory (see setPackagesToScan).
persistence.xml must always be present within META-INF directory in the classpath. More on where should META-INF be present for different types of java applications can be found here.
Persistence units are defined by the persistence.xml configuration file. The JAR file or directory whose META-INF directory contains persistence.xml is called the root of the persistence unit. The scope of the persistence unit is determined by the persistence unit’s root.
Each persistence unit must be identified with a name that is unique to the persistence unit’s scope.
Persistent units can be packaged as part of a WAR or EJB JAR file, or can be packaged as a JAR file that can then be included in an WAR or EAR file.
If you package the persistent unit as a set of classes in an EJB JAR file, persistence.xml should be put in the EJB JAR’s META-INF directory.
If you package the persistence unit as a set of classes in a WAR file, persistence.xml should be located in the WAR file’s WEB-INF/classes/META-INF directory.