一尘不染

JPA继承

hibernate

嗨,我是JPA的新手,我在理解它如何处理继承方面遇到困难。

我有一个需要解决的特定问题,而无需更改数据库方案,但是如果您找不到解决方案,我将感谢使用其他数据库方案的解决方案建议(欢迎使用Hibernate /
TopLink解决方案)。

如果我不清楚或您需要更多信息,请告诉我。提前致谢!

我有这个数据库:

TABLE Fruit
Id Varchar (10) Primary Key
size Varchar (10)
fruit_type Varchar(10)

TABLE Apple
Id Varchar (10) Primary Key Foreign Key references Fruit.Id
Apple_Property Varchar(10)

到目前为止,我的实体看起来像这样:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="fruit_type", discriminatorType=DiscriminatorType.Char)
@DiscriminatorValue(value="fruit")

public class Fruit implements Serializable {

    @Id
    protected String Id;

    protected String size;
}

@Entity
@DiscriminatorValue(value="apple")
//@PrimaryKeyJoinColumn(name="Id" , referencedColumnName="Id")

public class Apple extends Fruit implements Serializable {

    private String Apple_Property;
}

目前,我能够持久地保存Fruit对象。.仅当尚未持久化其Fruit对象时,Apple对象才能持久。

如果我尝试使用已经存在的Fruit对象来保留一个Apple对象:

Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);

我将收到一个错误消息,因为JPA尝试在水果表上创建一个已经存在的Id =“ 1”的新行。

..


阅读 250

收藏
2020-06-20

共1个答案

一尘不染

当使用JPA持久化子对象(即provider.create(apple1)您的情况)时,一条记录将插入到子表及其所有父表中。因此,provider.create(apple1)将一条记录插入到Fruit并将一条记录插入到Apple表。

在您的示例中,如果只想保留一个Apple对象,只需调用provider.create(apple1)就足够了。它将水果引用也保留在苹果对象内。

顺便说一句,我建议Fruit Table的PK为数字类型,并用于@GeneratedValue标记Fruit
bean的ID字段。这样,您可以让数据库为您生成一个ID,而不再需要在Java代码中显式设置它,以避免由于在Java代码中设置了一个已经存在的ID而导致此“
ID已经存在错误”。

2020-06-20