3

嗨,我是 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 对象。Apple 对象仅在其 Fruit 对象尚未持久化时才会持久化。

如果我尝试使用已经持久化的 Fruit 对象来持久化苹果对象:

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

我会得到一个错误,因为 JPA 尝试在 Fruit 表上创建一个 Id="1" 已经存在的新行。

..

4

4 回答 4

3

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

在您的示例中,如果您只想保留一个苹果对象,只需调用即可provider.create(apple1)。它也会将水果引用保留在苹果对象中。

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

于 2011-05-07T08:49:27.687 回答
1

我认为这完全按照设计工作。当您使用联合继承并持久化一个苹果对象时,JPA 将自动插入到苹果表和水果表中。您不需要在实体类中建模其他关系或 JoinColumn。

于 2011-05-07T07:53:41.240 回答
0

您在创建 db 表时尝试使用 java 继承概念,这在这种情况下是不可能的。我可以为这个问题考虑一种不同的方法。有表fruit_type 和fruit。fruit_type(id, typename,desc) fruit(id, name, type_id, desc) 这里 type_id 是外键。

于 2011-05-07T04:24:58.653 回答
0

我有同样的问题,到目前为止,我发现的唯一方法是查询父级并用父级构造子级。然后删除父级并重新创建两条记录。

于 2016-06-21T22:56:30.187 回答