【发布时间】:2019-03-21 02:10:04
【问题描述】:
在我的项目中,我使用 Spring Data Lovelace、Spring 5.1.1 和 Eclipselink 2.7.3 通过com.ethlo.persistence.tools:eclipselink-maven-plugin:2.7.1.1 插件进行静态编织。另外,我使用的是 OpenJDK 11。
构建工作正常,eclipselink-maven-plugin 被执行。它会生成一个在我看来很好的persistence.xml。
但是当我运行测试时,我得到了一个
Caused by: java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.example.MyEntity] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.example.MyEntity</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element.
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.entityEmbeddableManagedTypeNotFound(MetamodelImpl.java:180)
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:527)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:188)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:139)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:123)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:64)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
at org.springframework.data.util.Lazy.get(Lazy.java:94)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1804)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1741)
... 57 more
我已经试过了:
- 使用 Java 8:这解决了问题,但我想使用 Java 11。
- 手动将
<exclude-unlisted-classes>false</exclude-unlisted-classes>插入persistence.xml:没有区别,但话又说回来,无论如何,此属性“不适用于Java SE 持久性单元” - 将
eclipselink.weavingjpa 属性设置为false,就像在 Spring Data Eclipselink example project 中一样:没有区别
更新:
我调试了eclipselink初始化,它不“知道”我的实体类。在MetadataProcessor#initPersistenceUnitClasses 中,它们出现在classNames 列表中(因此persistence.xml 被正确摄取)。然后 Eclipselink 遍历所有找到的类名,并(以及其他)尝试通过调用 PersistenceUnitProcessor.isEntity(..) 来查找 @Entity 注释,而 PersistenceUnitProcessor.isEntity(..) 又调用 candidateClass.isAnnotationPresent("javax.persistence.Entity") - 并且返回 false。
换句话说:根本问题似乎是 Eclipselink 在我的实体类上看不到@Entity 注释(当然存在)。
更新 2:
我通过将<property name="eclipselink.logging.level" value="ALL"/> 插入persistence.xml 来启用eclipselink 日志记录并得到以下输出:
[EL Warning]: metamodel: 2018-10-17 08:15:13.449--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
[EL Warning]: metamodel: 2018-10-17 08:15:13.464--The collection of metamodel [ManagedType] types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. The lookup on [class de.viaprinto.backoffice.elasticsearch.persistence.entity.ElasticsearchIndex] will return null.
[EL Warning]: metamodel: 2018-10-17 08:15:13.464--The collection of metamodel [ManagedType] types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. The lookup on [class de.viaprinto.backoffice.elasticsearch.persistence.entity.ElasticsearchIndex] will return null.
所以,那里没有新信息。
更新 3:
情节变厚了:我调试了 eclipselink 如何构建其类元数据(在其中找不到 @Entity 注释)。它为此使用 ASM 而不是使用反射。更准确地说,它使用自己重新打包的(在这种情况下)ASM 6.2 版本(重新打包为org.eclipse.persistence:org.eclipse.persistence.asm:2.7.3)。在正确找到注释(在ClassReader:626 中)后,它会尝试Visit the NestedMembers attribute(ClassReader:651),但以UnsupportedOperationException 失败。 Eclipselink 捕获了这个异常并添加了一个“虚拟元数据类”(MetadataAsmFactory:143),其中不包含任何 Annotation 信息。
我发现issue in Spring's issue tracker 似乎描述了完全相同的问题。他们的解决方案是启用实验性 ASM 7 支持。还不知道如何在 eclipselink 中做到这一点。
我的实体类包含一个似乎引发问题的嵌套类(准确地说是枚举)。
【问题讨论】:
标签: java spring-data-jpa spring-data eclipselink