Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA OneToMany列表未找到应继承的mappedBy属性_Java_Hibernate_Jpa_Inheritance_One To Many - Fatal编程技术网

Java JPA OneToMany列表未找到应继承的mappedBy属性

Java JPA OneToMany列表未找到应继承的mappedBy属性,java,hibernate,jpa,inheritance,one-to-many,Java,Hibernate,Jpa,Inheritance,One To Many,我们目前正在处理一些需求,我们必须向数据库中添加一些类似的实体(汽车图片、宠物图片、假日图片等),这些实体都属于一个所有者(个人)。我们不直接链接字节数组,而是使用引用。稍后可能会添加更多图片类型,因此为了保持低复杂性,我们希望将其直接链接到Java类,以便我们可以使用的实例和类似的东西。我们希望对超类PictureRef使用@heritation,该超类包含公共属性并链接到person。然后还有另一个实体Person,它将有这些子类的列表。这是一个带有映射属性的OneToMany关系。此map

我们目前正在处理一些需求,我们必须向数据库中添加一些类似的实体(汽车图片、宠物图片、假日图片等),这些实体都属于一个所有者(个人)。我们不直接链接字节数组,而是使用引用。稍后可能会添加更多图片类型,因此为了保持低复杂性,我们希望将其直接链接到Java类,以便我们可以使用的
实例和类似的东西。我们希望对超类
PictureRef
使用
@heritation
,该超类包含公共属性并链接到person。然后还有另一个实体
Person
,它将有这些子类的列表。这是一个带有映射属性的
OneToMany
关系。此
mappedBy
属性未知,因此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实体都派生自一个抽象实体,该实体包含id和审核值。这可以正确地处理其他子类,所以我认为这个类不会引起问题

抽象实体

@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
// Sequence definition removed
private Long id;
// other values are following //
}
2) 然后我们有一个超类,它必须包含一个公共属性。所有派生类都必须写在一个表中(因为它们看起来非常相似)。此外,我们将拥有直接与该实体一起工作的业务逻辑,例如,按id加载或删除

图片ref

@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;
}
@Entity
@DiscriminatorValue("car")
public class CarPictureRef extends PictureRef {

@Column(name="licence_plate_visible")
private boolean licensePlateVisible;
}
@Entity
@DiscriminatorValue("holiday")
public class HolidayPictureRef extends PictureRef {

@Column(name="weather_condition")
private String weatherCondition;
}
3) 那么至少有两个子类。很快就会有更多。它们将包含仅与此类图片相关的属性

类别CarPictureRef

@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;
}
@Entity
@DiscriminatorValue("car")
public class CarPictureRef extends PictureRef {

@Column(name="licence_plate_visible")
private boolean licensePlateVisible;
}
@Entity
@DiscriminatorValue("holiday")
public class HolidayPictureRef extends PictureRef {

@Column(name="weather_condition")
private String weatherCondition;
}
班级度假图片ref

@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;
}
@Entity
@DiscriminatorValue("car")
public class CarPictureRef extends PictureRef {

@Column(name="licence_plate_visible")
private boolean licensePlateVisible;
}
@Entity
@DiscriminatorValue("holiday")
public class HolidayPictureRef extends PictureRef {

@Column(name="weather_condition")
private String weatherCondition;
}
4) 然后是拥有/上传所有这些图片的人。此人拥有每种图片的列表,因为应用程序对它们的处理确实不同。每个列表都包含具体的子类,但是对于
mappedBy
属性,我们使用超类
PictureRef
中的
person
。也许这种继承是不可能的

@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 //
}

您已经找到了JPA规范中没有包含的任何详细信息。JPA规范2.11规定:

一个实体可以从另一个实体类继承。实体支持 继承、多态关联和多态查询

这种支持到底是什么还没有定义

当您尝试将
@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;

    ...

}
因此,在将mappedBy解析为子类时,Hibernate不允许继承字段(
person
)。然而,关系定义中有足够的信息来解决这些关系,EclipseLink很好地做到了这一点

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

使用此解决方案,您可以将
@OneToMany
映射保留在
Person
中。不幸的是,这在Hibernate中不起作用,因为Hibernate将查找具有正确person\u ID的任何子实体(本例中为any
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;

    ...

}
@实体
@表(name=“t_person”)
//序列定义已删除
公共类Person扩展抽象实体{
@OneToMany(mappedBy=“person”,targetEntity=PictureRef.class)
私人列表图片;
...
}

然后,您将有一个PictureRefs列表,它将是任何子类。您可以测试列表中的项目,并设置包含每个所需子类型的临时字段。因此,在这个程度上,Hibernate支持多态关联,但eclipseLink做得更多,所以要注意可移植性问题。

对于类似的场景,可以通过使用@JoinColumn而不是mappedBy以及@where(子句=“discriminator value”)来解决它。 然而,奇怪的是,为什么这个问题自2008年以来一直没有得到解决。

谢谢您的帮助,但这不就是将所有图片都列在一个列表中的结果吗?我们希望实现JPA根据单独列表中的具体子类直接检索所有图片,这样就不必考虑正确的映射。因为我认为只有通过JPA/Hibernate功能才能实现这个用例?实际上,在EclipseLink中,您的方法对我来说似乎很好…。你能发布导致错误的持久性调用的服务代码吗?EclipseLink很有趣。所以可能是hibernate问题,而不是JPA的一般问题。该错误发生在应用程序部署时的启动过程中。我添加了完整的堆栈跟踪-如果有帮助的话。谢谢你的第二个(/编辑)答案!对于我们当前的特性,我们将坚持休眠并将所有图片存储为一个实体,在检索时根据类型列进行过滤。从长远来看,切换到eclipse链接将是不可避免的。我很惊讶Hibernate不支持这种用例,我认为这种用例并不罕见。