14

问题

我正在编写一个独立的实用程序,给定一个包含 JPA-2 注释持久性单元的 jar,需要以编程方式获取我在特定持久性单元中的所有 @Entity 类的列表。

我想决定两种方法中的哪一种是获取这些信息的方法,以及为什么;或者如果有另一种我没有想到的更好的方法。

解决方案 1

Java 程序将 jar 放在类路径中,使用 JavaSE 方法从 jar 中的类创建持久性单元。然后它使用 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

程序扫描指定 jar 中的目录和文件以查找 persistence.xml 文件,然后找到具有指定持久性单元名称的文件。然后 XPath 文件以获取<class>XML 元素列表并从那里读取完全限定的类名。根据名称,构建类令牌。

限制/担忧

  • 如果可能的话,我想采用方法 1。
  • 此实用程序不会在容器内运行,但 jar 是一个 EJB 项目,旨在在容器内运行。这将如何成为问题?
  • 该实用程序将在类路径上提供 Open-EJB,以获取所有 Java EE 6 类的实现。
  • 尽管 EJB 项目是为在 Hibernate 上运行而构建的,但该实用程序不应该是特定于 Hibernate 的。
  • 有没有绊脚石?
4

2 回答 2

14

如果有人感兴趣,解决方案 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
    }
  }

关键是覆盖我的事务类型并清除我的 persistence.xml 中定义的 jtaDataSource。原来一切都是不必要的。

于 2012-04-14T02:20:06.990 回答
1

如果您的 jar 格式正确(persistence.xml 在正确的位置 - 在 META-INF 文件夹中),那么一切看起来都很好。

不必在容器内运行您的实用程序,JPA 不是 JavaEE 规范的一部分。

于 2012-04-12T03:21:31.207 回答