我的eclipse工作区里有两个maven项目。第一个项目有hibernate实体,应该在第二个项目中使用。我在第二个项目中将其添加为依赖项:
<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实体包扫描。
谢谢, 卓然
答案 0 :(得分:1)
[编辑]此问题已在Hibernate 5.0.7中解决,请参阅HHH-4161。
根据HHH-4161的最新更新,Hibernate 5.0.2上也会出现此问题,计划在Hibernate 5.0.5中解决。
在本期中,I proposed a workaround基于自定义Scanner类,该类管理相对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的拉取请求(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
表不存在的问题,这表明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
我在之前的一个客户中使用的另一个解决方法是在构建时根据应用程序类路径中JAR的依赖关系构建<class>
标记列表。它看起来有点复杂,但它对应用程序提供了很好的控制:开发人员可以查看persistence.xml以立即知道将在运行时加载哪些实体类。请注意,在我考虑自定义扫描程序解决方法之前很久就使用了这种方法。