在 eclipse 中找不到来自 persistence.xml 的 jar 文件

jar-file from persistence.xml is not found in eclipse

我的 eclipse 工作区中有两个 Maven 项目。第一个项目有应在第二个项目中使用的休眠实体。我将它添加为第二个项目中的依赖项:

<dependency>
        <groupId>org.prosolo</groupId>
        <artifactId>bigdata.common</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

我禁用了工作区解析,因此 bigdata.common-0.0.1-SNAPSHOT.jar 列在 Maven 依赖项下。此外,我配置 persistence.xml 导入这个 jar 文件:

<persistence-unit name="entityManager"
    transaction-type="RESOURCE_LOCAL">      
    <jar-file>lib/bigdata.common-0.0.1-SNAPSHOT.jar</jar-file>

但是,当我从 eclipse 运行 项目时,EntityManager 由于以下错误而无法初始化:

Caused by: java.lang.IllegalArgumentException: File [lib/bigdata.common-0.0.1-SNAPSHOT.jar] referenced by given URL [file:lib/bigdata.common-0.0.1-SNAPSHOT.jar] does not exist

如果我 运行 从终端项目或如果我使用 .jar 文件的绝对路径没有问题,但相对路径问题在 Eclipse 中仍然存在。在这两种情况下,我都将 maven-jetty-plugin 用于 运行 应用程序。

我找到了这个错误报告 https://hibernate.atlassian.net/browse/HHH-4161,但似乎没有解决方案。

我想知道这个问题是否有任何解决方案,或者如果不能使用 jar 文件,我应该使用什么其他方法来使用来自其他项目的休眠实体进行包扫描。

谢谢, 卓然

[编辑] 该问题已在 Hibernate 5.0.7 中解决,请参阅 HHH-4161

根据 HHH-4161.

的最新更新,此问题也发生在 Hibernate 5.0.2 中,计划在 Hibernate 5.0.5 中解决

在本期中,I proposed a workaround 基于自定义扫描程序 class,它管理相关 URL 并将它们绝对化。我将AbstractScannerImpl源码复制到test.MyCustomScanner,添加了StandardScanner的构造函数,并在environment.getNonRootUrls()循环中添加了如下代码:

if (!url.getPath().startsWith("/")) {
    // relative URL => make it processed relatively to the root URL of the META-INF/persistence.xml
    // This means that rootUrl has a META-INF directory (but the rootUrl has no META-INF in path).
    // See JPA 2.1 specification page 366-368: http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf
    // Note: while the solution looks smart, the getNonRootUrls may include more
    // than the <jar-file>. Thus, it may have side effects.
    try {
        URL absoluteUrl = new URL(environment.getRootUrl(),url.getPath());
        url=absoluteUrl;
    } catch (MalformedURLException e) {
        throw new RuntimeException("cannot make the relative URL as absolute:"+url);
    }
}

精神与 Lauri Harpf 的 pull request (https://github.com/hibernate/hibernate-orm/pull/889/files) 相同,但优先考虑相对 URL 并使用相对 URL 测试而不是异常捕捉机制。

这种方法的风险在于,所有非根 URL 都以相同的方式管理,而不仅仅是 <jar-file> 标签。因此,可能会出现副作用。 然后将自定义扫描仪添加到 persistence.xml:

<property name="hibernate.ejb.resource_scanner" value="test.MyCustomScanner" />

当运行时,执行日志显示没有异常,只提出了MyEntity table不存在的问题,这表明entities.jar已经处理完毕正确:

oct. 30, 2015 8:11:50 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
    name: test-hibernate2
    ...]
oct. 30, 2015 8:11:51 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.2.Final}
oct. 30, 2015 8:11:51 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
oct. 30, 2015 8:11:51 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
oct. 30, 2015 8:11:51 PM org.hibernate.boot.internal.MetadataBuilderImpl$MetadataBuildingOptionsImpl <init>
INFO: HHH90000001: Found usage of deprecated setting for specifying Scanner [hibernate.ejb.resource_scanner]; use [hibernate.archive.scanner] instead
oct. 30, 2015 8:11:51 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.0.Final}
oct. 30, 2015 8:11:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
oct. 30, 2015 8:11:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [org.hsqldb.jdbcDriver] at URL [jdbc:hsqldb:mem:testdb]
oct. 30, 2015 8:11:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=sa}
oct. 30, 2015 8:11:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
oct. 30, 2015 8:11:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
oct. 30, 2015 8:11:51 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
oct. 30, 2015 8:11:52 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
oct. 30, 2015 8:11:52 PM org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults
INFO: HHH000262: Table not found: MyEntity
oct. 30, 2015 8:11:52 PM org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults
INFO: HHH000262: Table not found: MyEntity

我在我以前的一位客户中使用的另一种解决方法是在构建时根据应用程序 class 路径中 JAR 的依赖关系构建 <class> 标记列表。乍一看有点复杂,但它对应用程序提供了很好的控制:开发人员可以查看 persistence.xml 以立即知道将在 运行 加载哪个实体 classes时间。请注意,这种方法是在 2007 年使用的,远早于我想到自定义扫描仪解决方法。