加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – JPA OneToMany列表找不到应该继承的mappedBy属性

发布时间:2020-12-15 02:08:42 所属栏目:Java 来源:网络整理
导读:我们目前正在制定一些要求,我们必须在数据库中添加一些类似的实体(汽车图片,宠物图片,假日图片……),这些图片都属于一个所有者(人).我们不直接链接字节数组,但使用引用.之后可能会添加更多的图片类型,以便保持低复杂性,我们希望将其直接链接到 Java类,以便我
我们目前正在制定一些要求,我们必须在数据库中添加一些类似的实体(汽车图片,宠物图片,假日图片……),这些图片都属于一个所有者(人).我们不直接链接字节数组,但使用引用.之后可能会添加更多的图片类型,以便保持低复杂性,我们希望将其直接链接到 Java类,以便我们可以使用实例和类似的东西.我们希望将@Inheritance用于超类PictureRef,它包含常用属性以及指向此人的链接.然后是另一个实体Person,它将包含这些子类的列表.这是与mappedBy属性的OneToMany关系.此mappedByattribute未知,因此JPA会将此错误返回给我们:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown
target entity property:  de.company.project.somepackages.PictureRef.person 
in de.company.project.somepackages.Person.picturesOfCars

我认为最好用下面的代码说明.为了便于阅读,我删除了其他属性和getter / setter以及id序列.

1)所有JPA Entites都是从一个包含id和审计值的抽象实体派生的.这适用于其他子类,所以我不认为这个类会导致问题.

类AbstractEntity

@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
// Sequence definition removed
private Long id;
// other values are following //
}

2)然后我们有一个超类,它必须包含一个共同的属性.所有派生类都必须写在一个表中(因为它们看起来非常相似).此外,我们将具有直接与该实体一起工作的业务逻辑,例如,按ID加载或删除.

类图片参考

@Entity
@Table(name = "t_picture_ref")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "picture_type")
// Sequence Definition removed
public class PictureRef extends AbstractEntity {
// common attributes,e.g. name or link to file //

@ManyToOne
@JoinColumn(name = "person_id")
private Person person;
}

3)然后至少有两个子类.更多即将到来.它们将包含仅与此类图片相关的属性.

CarPictureRef类

@Entity
@DiscriminatorValue("car")
public class CarPictureRef extends PictureRef {

@Column(name="licence_plate_visible")
private boolean licensePlateVisible;
}

类HolidayPictureRef

@Entity
@DiscriminatorValue("holiday")
public class HolidayPictureRef extends PictureRef {

@Column(name="weather_condition")
private String weatherCondition;
}

4)然后是拥有/上传所有这些图片的人.这个人有各种图片的列表,因为它们被应用程序处理得非常不同.每个列表都包含具体的子类,但对于mappedBy属性,我们使用超类PictureRef中的人.也许这种遗传是不可能的?

班级人员

@Entity
@Table(name = "t_person")
// Sequence Definition removed
public class Person extends AbstractEntity {

@OneToMany(mappedBy = "person",targetEntity = CarPictureRef.class)
private List<CarPictureRef> picturesOfCars;

@OneToMany(mappedBy = "person",targetEntity = HolidayPictureRef.class)
private List< HolidayPictureRef> picturesOfHolidays;

// a lot of other fields following //
}

一种解决方法可能是只将所有属性存储在一个表中(我们还想做),然后只存储一个Entity PictureRef.然后我们将在后端编写应用程序逻辑,用于评估pictureType并为相应的业务案例创建新类.但这看起来有点丑陋 – 我希望有一个JPA解决方案用于这个常见的用例?
也许我们只缺少一个或多个注释?

为了完整起见,我添加了完整的堆栈跟踪.我们正在使用Hibernate 4.3.8.Final,并且在部署到WildFly 8.2.0.Final期间发生错误.

21:19:24,283 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 88) MSC000001: Failed to start service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": org.jboss.msc.service.StartException in service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_25]
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:474) [wildfly-security-manager-1.0.0.Final.jar:1.0.0.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.1.Final.jar:2.1.1.Final]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:855) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.hibernate4.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44) [jipijapa-hibernate4-3-1.0.1.Final.jar:]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
... 8 more
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property:  
de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:768) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:728) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
... 13 more

21:19:24,291 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 2) JBAS014613: Operation ("deploy") failed - address: ([("deployment" => "Example-1.0-SNAPSHOT.war")]) - failure description: {"JBAS014671: Failed services" => {"jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars"}}
21:19:24,292 ERROR [org.jboss.as.server] (management-handler-thread - 2) JBAS015870: Deploy of deployment "Example-1.0-SNAPSHOT.war" was rolled back with the following failure message: 
{"JBAS014671: Failed services" => {"jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars"}}

解决方法

您已经详细了解了JPA规范中未涉及的区域. JPA Spec 2.11规定:

An entity may inherit from another entity class. Entities support
inheritance,polymorphic associations,and polymorphic queries.

究竟是什么支持没有定义.

当您尝试将@OneToMany映射到继承@ManyToOne关系的子类时……

public class Person extends AbstractEntity {

    @OneToMany(mappedBy = "person",targetEntity = CarPictureRef.class)
    private List<CarPictureRef> picturesOfCars;

    @OneToMany(mappedBy = "person",targetEntity = HolidayPictureRef.class)
    private List< HolidayPictureRef> picturesOfHolidays;

    ...

}

Hibernate抱怨

mappedBy reference an unknown target entity property

因此,在将mappedBy解析为子类时,Hibernate不允许继承字段(本例中为person).但是,关系定义中有足够的信息来解决这些关系,EclipseLink非常好地完成了这些.

可以将@ManyToOne从super(PictureRef)转移到具体的子类(CarPictureRef等)

@Entity
public class CarPictureRef extends PictureRef {

    @ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

    ...

}

使用此解决方案,您可以将@OneToMany映射保留在Person中.不幸的是,这在Hibernate中不起作用,因为Hibernate将查找具有正确person_ID的任何子实体(在本例中为任何pictureRef子类),然后抱怨找到的类型是错误的类型

org.hibernate.WrongClassException: Object [id=55] was not of the specified subclass.

同样,Hibernate可以通过使用Discriminator列来解决这个问题,但事实并非如此,而且这也是EclipseLink所做的事情.

你的方法是为每个子类指定一个不同的连接列,这意味着当每个新的子类出现时,你需要修改你认为不理想的表.

使用Hibernate,您可以在@OneToMany关系上定位PictureRef超类,以便Person实体成为;

@Entity
@Table(name = "t_person")
// Sequence Definition removed
public class Person extends AbstractEntity {

    @OneToMany(mappedBy = "person",targetEntity = PictureRef.class)
    private List<PictureRef> pictures;

    ...

}

然后,您将拥有一个PictureRef列表,它将成为任何子类.您可以测试列表中的项目并设置包含每个所需子类型的瞬态字段.所以在这个程度上,Hibernate支持多态关联,但eclipseLink做了很多,所以要注意可移植性问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读