Подтвердить что ты не робот

Как я могу получить все классы @Entity из единицы сохранения?

Проблема

Я пишу автономную служебную программу, которая, учитывая банку, содержащую аннотированный блок сохранения JPA-2, должна программно получить список всех моих классов @Entity в определенном модуле сохранения.

Я хотел бы решить, какой из двух подходов был бы способом получить эту информацию и почему; или если есть еще один лучший способ, о котором я не думал.

Решение 1

Java-программа помещает jar в путь к классам, создает блок персистентности из классов в банке с использованием методологий JavaSE. Затем он использует классы javax.persistence для получения метамодели JPA, отталкивает список токенов класса от этого.

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

Решение 2

Просканируйте каталоги и файлы внутри указанной банки для файлов persistence.xml, затем найдите один с указанным именем единицы сохранения. Затем XPath файл, чтобы получить список элементов <class> XML и прочитать от него полные имена классов. Из имен введите маркеры класса.

Ограничения/Обеспокоенность

  • Я хотел бы пойти с подходом 1, если это возможно.
  • Эта утилита НЕ запускается внутри контейнера, но банка представляет собой проект EJB, предназначенный для запуска внутри него. Как это будет проблемой?
  • Утилита будет иметь Open-EJB, доступную на пути к классам, для получения реализаций всех классов Java EE 6.
  • Несмотря на то, что проект EJB построен для работы в Hibernate, утилита не должна быть спецификацией Hibernate.
  • Есть ли какие-либо камни преткновения?
4b9b3361

Ответ 1

Если ваша банка хорошо сформирована (persistence.xml в нужном месте - в папке META-INF), все выглядит нормально.

Нет необходимости запускать вашу утилиту внутри контейнера, JPA не является частью спецификаций JavaEE.

Ответ 2

В случае, если кто-то заинтересован, решение 1 работало. Здесь, по сути, я должен был сделать:

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
    }
  }

Ключ должен был переопределить мой тип транзакции и затушить jtaDataSource, который был определен в моем файле persistence.xml. Оказывается, все остальное не нужно.