[英]JPA many-to-many with extra columns using @IdClass fails in springTestContextPreparation Hibernate AnnotationException “has no persistent id property”
I am trying to represent a bidirectional relationship with some entities using the @IdClass
annotation as is shown in this answer: https://stackoverflow.com/a/32920550/8977519 我试图使用
@IdClass
注释表示与某些实体的双向关系,如下面的答案所示: https : @IdClass
I have a solution setup that follows the linked answer exactly and the application runs fine. 我有一个解决方案设置完全遵循链接的答案,应用程序运行正常。 I am able to use all of my CRUD end points and the changes are reflected in the DB.
我能够使用我的所有CRUD端点,并且更改会反映在数据库中。 However, when I try to execute my tests the
springTestContextPrepareTestInstance
step fails. 但是,当我尝试执行测试时,
springTestContextPrepareTestInstance
步骤失败。
Composite Id Class 复合Id类
@Getter
@Setter
@EqualsAndHashCode
public class CompositeId implements Serializable {
private static final long serialVersionUID = ...;
@Type(type = "uuid-char")
private UUID entity1;
@Type(type = "uuid-char")
private UUID entity2;
}
Bidirectional Entity Class 双向实体类
@Entity
@Table(name = "bidirectional_entity")
@NoArgsConstructor
@Getter
@Setter
@IdClass(CompositeId.class)
public class BidirectionalEntity {
@Id
@ManyToOne
@JoinColumn(name = "entity1_id", referencedColumnName = "id")
private Entity1 entity1;
@Id
@ManyToOne
@JoinColumn(name = "entity2_id", referencedColumnName = "id")
private Entity2 entity2;
...
}
Entity Classes 实体类
@Entity
@Table(name = "entity1")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class Entity1 {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(generator = "uuid2")
@Column(name = "id", updatable = false)
@Type(type = "uuid-char")
private UUID id;
@OneToMany(mappedBy = "entity1", orphanRemoval=true, cascade = CascadeType.ALL)
@Setter(AccessLevel.NONE)
private List<BidirectionalEntity> entities = new ArrayList<>();
...
}
@Entity
@Table(name = "entity2")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class Entity2 {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(generator = "uuid2")
@Column(name = "id", updatable = false)
@Type(type = "uuid-char")
private UUID id;
@OneToMany(mappedBy = "entity2", orphanRemoval=true, cascade = CascadeType.ALL)
@Setter(AccessLevel.NONE)
private List<BidirectionalEntity> entities = new ArrayList<>();
...
}
The error given is: 给出的错误是:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: {CompositeId Class} has no persistent id property
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:145)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:168)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:105)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: org.hibernate.AnnotationException: {CompositeId Class} has no persistent id property
at org.hibernate.cfg.AnnotationBinder.bindIdClass(AnnotationBinder.java:2858)
at org.hibernate.cfg.AnnotationBinder.mapAsIdClass(AnnotationBinder.java:1053)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:781)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:250)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:231)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:274)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
... 45 more
Update 更新
After doing some novice debugging, in the Hibernate Core (5.3.9) AnnotationBinder
class -> bindIdClass
method the componentId
object properties
list is empty when performing setup for test(obviously, it's what is checked to throw the error). 在做了一些新手调试之后,在Hibernate Core(5.3.9)
AnnotationBinder
类 - > bindIdClass
方法中,当执行测试设置时, componentId
对象properties
列表为空(显然,它是检查抛出错误的内容)。 However, when running the program normally, there are two properties of value
org.hibernate.mapping.SimpleValue([org.hibernate.mapping.Column(entity*_id)])
with name
entity*. 但是,在正常运行程序时,有两个属性
value
org.hibernate.mapping.SimpleValue([org.hibernate.mapping.Column(entity*_id)])
,其name
entity *。 Matching up with the BidirectionalEntity
class as it should be. 与
BidirectionalEntity
类匹配应该是。
I have figured out the issue. 我已经弄明白了这个问题。 Along with my service tests I was also writing tests to verify constraint validation annotations on POJOs.
除了我的服务测试,我还编写了测试来验证POJO上的约束验证注释。 I forgot to add 'Test' to the end of the
CompositeId
test class name ( CompositeIdTest
). 我忘了将“Test”添加到
CompositeId
测试类名称( CompositeIdTest
)的末尾。 It seems that in the spring test context checking the test class was getting pulled in and checked for ID properties by Hibernate. 似乎在Spring测试上下文检查中,测试类被Hibernate拉入并检查了ID属性。 Once I changed the test class name, tests starting running fine.
一旦我更改了测试类名称,测试开始运行正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.