Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get all @Entity classes from a Persistence Unit?

Problem

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.

Solution 1

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();

Solution 2

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.

Constraints/Concerns

  • I'd like to go with approach 1 if possible.
  • This utility will NOT run inside a container, but the jar is an EJB project designed to run inside one. How will this be a problem?
  • The utility will have Open-EJB available on the classpath to get implementations of all the Java EE 6 classes.
  • Even though the EJB project is built to run on Hibernate, the utility should not be Hibernate-specific.
  • Are there any stumbling blocks?
like image 549
Tom Tresansky Avatar asked Apr 11 '12 16:04

Tom Tresansky


People also ask

Which elements belong to persistence unit in persistence xml?

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.

Where does persistence xml go in ear?

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.

Which method in JPA is used to retrieve the entity based on its primary keys?

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.


2 Answers

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.

like image 155
Tom Tresansky Avatar answered Oct 07 '22 23:10

Tom Tresansky


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.

like image 29
Alexander Mitenko Avatar answered Oct 07 '22 22:10

Alexander Mitenko