我使用的是SpringBootV1.5.3,当我使用Hibernate继承时,当父实体和子实体中都有同名的属性时,就会发生AnnotationException: mappedBy reference an unknown target entity property
。
例如:
Apple => RedApple
=> GreenApple
=> etc.
Tree => RedAppleTree
=> GreenAppleTree
=> etc.
// Tree.java
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@EqualsAndHashCode(exclude = {"apples"})
@DiscriminatorColumn(name = "colour")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Tree {
@Id
@GeneratedValue
private Long id;
}
// RedAppleTree.java
@Entity
@Table(name = "tree")
@DiscriminatorValue("RED")
public class RedAppleTree extends Tree {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "tree")
private List<RedApple> apples;
}
// Apple.java
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@DiscriminatorColumn(name = "colour")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Apple {
@Id
@GeneratedValue
private Long id;
@Enumerated(EnumType.STRING)
@Column(insertable = false, updatable = false)
private Colour colour;
@JoinColumn(insertable = false, updatable = false)
@ManyToOne
private Tree tree;
}
// RedApple.java
@Entity
@Table(name = "apple")
@DiscriminatorValue("RED")
public class RedApple extends Apple {
@JoinColumn(insertable = false, updatable = false)
@ManyToOne
private RedAppleTree tree;
}
// Colour.java
public enum Colour {
RED,
GREEN,
}
Apple.tree
和RedApple.tree
同时存在。在父Apple
中,类型是Tree
;在子RedApple
中,类型是RedAppleTree
。
现在,当项目运行时,我得到:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.example.demo.dao.RedApple.tree in com.example.demo.dao.RedAppleTree.apples
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean (AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:314)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1162)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1151)
at com.example.demo.DemoApplication.main (DemoApplication.java:13)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:527)
at java.lang.Thread.run (Thread.java:834)
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.example.demo.dao.RedApple.tree in com.example.demo.dao.RedAppleTree.apples
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass (CollectionBinder.java:769)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass (CollectionBinder.java:719)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass (CollectionSecondPass.java:54)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses (InFlightMetadataCollectorImpl.java:1655)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses (InFlightMetadataCollectorImpl.java:1623)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete (MetadataBuildingProcess.java:278)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata (EntityManagerFactoryBuilderImpl.java:847)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build (EntityManagerFactoryBuilderImpl.java:874)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory (SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory (LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory (AbstractEntityManagerFactoryBean.java:370)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet (AbstractEntityManagerFactoryBean.java:359)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods (AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1624)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean (AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:314)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1162)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1151)
at com.example.demo.DemoApplication.main (DemoApplication.java:13)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:527)
at java.lang.Thread.run (Thread.java:834)
现在我可以重命名其中一个属性来解决这个问题,但在我正在处理的实际项目中,它会导致更多的更改。
是否可以保持属性名称不变?
发布于 2020-10-23 14:41:36
在你的父类和子类中复制你的"tree“属性是一个问题。我相信这里的例子会做你想要的。
Tree.java
@Entity
@Table(name = "tree")
@DiscriminatorColumn(name = "colour")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Tree<APPLE extends Apple> {
@Id
@GeneratedValue
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "tree", targetEntity = Apple.class)
private Set<APPLE> apples = Sets.newHashSet();
//... getters & setters
}
Apple.java
@Table(name = "apple")
@Entity
@DiscriminatorColumn(name = "colour")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Apple<TREE extends Tree> {
@Id
@GeneratedValue
private Long id;
@JoinColumn(name = "tree_id")
@ManyToOne(targetEntity = Tree.class)
private TREE tree;
}
RedAppleTree.java
@Entity
@Table(name = "tree")
@DiscriminatorColumn(name = "colour")
@DiscriminatorValue("RED")
public class RedAppleTree extends Tree<RedApple> {
}
RedApple.java
@Entity
@Table(name = "apple")
@DiscriminatorColumn(name = "colour")
@DiscriminatorValue("RED")
public class RedApple extends Apple<RedAppleTree> {
}
这将创建以下DB表
create table tree (
colour varchar(31) not null,
id bigint generated by default as identity (start with 1),
primary key (id)
);
create table apple (
colour varchar(31) not null,
id bigint generated by default as identity (start with 1),
tree_id bigint,
primary key (id)
)
然后,当我运行以下代码时
@Test
public void test() {
RedAppleTree tree = new RedAppleTree();
session.persist(tree);
GreenAppleTree greenTree = new GreenAppleTree();
session.persist(greenTree);
RedApple apple = new RedApple();
apple.setTree(tree);
session.persist(apple);
tree.getApples().add(apple);
session.flush();
session.clear();
tree = session.get(RedAppleTree.class, tree.getId());
System.err.println(session.createCriteria(RedAppleTree.class).list());
}
这将产生以下SQL (在启用hibernate-sql-logging的情况下运行)
Hibernate:
insert
into
tree
(id, version, colour)
values
(default, ?, 'RED')
Hibernate:
insert
into
tree
(id, version, colour)
values
(default, ?, 'GREEN')
Hibernate:
insert
into
apple
(id, version, tree_id, colour)
values
(default, ?, ?, 'RED')
Hibernate:
select
redappletr0_.id as id2_409_0_,
redappletr0_.version as version3_409_0_
from
tree redappletr0_
where
redappletr0_.id=?
and redappletr0_.colour='RED'
Hibernate:
select
this_.id as id2_409_0_,
this_.version as version3_409_0_
from
tree this_
where
this_.colour='RED'
我相信这应该可以解决你的基本问题。
发布于 2020-10-14 07:47:36
事实是,我从来没有遇到过类似的问题,合乎逻辑的事情,一个好的做法是更改属性的名称,以区分每个属性引用的实体,编译器会告诉您在哪里更改它。
您可以尝试在关系中指定子类,如下所示:
mappedBy = "tree", targetEntity = RedAppleTree.class
但我重申,最好的选择是更改属性的名称,即使这涉及到更多的工作。
https://stackoverflow.com/questions/64347162
复制相似问题