I'm writing a standalone utility program which, given a jar containing a JPA-2 annotated persistence unit, needs to programmatically get a list of all my @Entity classes in a particular persistence unit.
I'd like to decide which of 2 approaches would be the way to go to get this information, and why; or if there is another better way I haven't thought of.
Java program puts jar on the classpath, creates persistence unit from the classes in the jar using JavaSE methodologies. Then it uses the javax.persistence classes to get the JPA Metamodel, pull back list of class tokens from that.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MY_ PERSISTENCE_UNIT");
Metamodel mm = emf.getMetamodel();
// loop these, using getJavaType() from Type sub-interface to get
// Class tokens for managed classes.
mm.getManagedTypes();
Program scan the directories and files inside the specified jar for persistence.xml files, then finds one with the specified persistence unit name. Then XPath the file to get the list of <class>
XML elements and read the fully qualified class names from there. From names, build class tokens.
xml file. This file defines a persistence unit named OrderManagement, which uses a JTA-aware data source jdbc/MyOrderDB. The jar-file and class elements specify managed persistence classes: entity classes, embeddable classes, and mapped superclasses.
xml should be located in the WAR file's WEB-INF/classes/META-INF directory. If you package the persistence unit in a JAR file that will be included in a WAR or EAR file, the JAR file should be located: In the WEB-INF/lib directory of a WAR. In the EAR file's library directory.
The find() method used to retrieve an entity defined as below in the EntityManager interface. T find(Class<T> entityClass, Object primaryKey) – Returns entity for the given primary key. It returns null if entity is not found in the database.
In case anyone's interested, Solution 1 worked. Here's essentially what I had to do:
public MySQLSchemaGenerator() throws ClassNotFoundException {
Properties mySQLDialectProps = new Properties();
mySQLDialectProps.setProperty("javax.persistence.transactionType", "RESOURCE_LOCAL");
mySQLDialectProps.setProperty("javax.persistence.jtaDataSource", "");
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence_unit_name>", mySQLDialectProps);
final Metamodel mm = emf.getMetamodel();
for (final ManagedType<?> managedType : mm.getManagedTypes()) {
managedType.getJavaType(); // this returns the java class of the @Entity object
}
}
The key was to override my transaction type and blank out the jtaDataSource which had been defined in my persistence.xml. Turns out everything else was unnecessary.
If Your jar is well-formed (persistence.xml at the right place - in the META-INF folder), then all looks fine.
It is not necessary to run your utility inside a container, JPA is not a part of JavaEE specs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With