在我的项目中,我使用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
我已经尝试过:
<exclude-unlisted-classes>false</exclude-unlisted-classes>
插入persistence.xml
中:没有区别,但是再次,此属性仍然是“不适用于Java SE持久性单元” eclipselink.weaving
jpa属性设置为false
:没有区别 更新:
我调试了eclipselink初始化,但它不“知道”我的实体类。在MetadataProcessor#initPersistenceUnitClasses
中,它们出现在persistence.xml
列表中(因此正确摄取了classNames
)。 Eclipselink然后遍历所有找到的类名,并(其中包括)尝试通过调用@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
)。
我发现一个issue in Spring's issue tracker似乎描述了完全相同的问题。他们的解决方案是启用实验性ASM 7支持。尚不知道如何在eclipselink中做到这一点。
我的实体类包含一个嵌套类(准确地说是一个枚举),这似乎引发了问题。
答案 0 :(得分:2)
Eclipselink使用ASM来解析实体类并生成元数据,该元数据又被用来决定一个实体类是否实际上是一个实体(即带有@Entity
注释)。
在我的实体类中遇到“嵌套成员”(即嵌套枚举)时,ASM 6.2抛出UnsupportedOperationException
,这使eclipselink丢弃该类已收集的元数据并生成不包含注释的伪元数据。因此是错误。
有四种方法可以解决此问题:
ASM7_EXPERIMENTAL
构造函数中将ASM api级别设置为MetadataAsmFactory$ClassMetadataVisitor
。我尚未对此进行测试,但是根据this,它应该可以解决此问题。显然,此问题已在eclipselink master及其2.7分支中得到修复,因此该修复程序应在下一版本中可用。