java - JPA 继承

标签 java hibernate inheritance jpa toplink

您好,我是 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 对象来持久化一个 apple 对象:

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

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

..

最佳答案

当使用 JPA 保留子对象时(即 provider.create(apple1) 在您的例子中),一条记录将被插入到子表及其所有父表中。因此 provider.create(apple1) 将向 Fruit 表插入一条记录,并向 Apple 表插入一条记录。

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

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

关于java - JPA 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5919091/

相关文章:

java - 从 Servlet(或过滤器)访问 Tomcat 内部

java - 集群中的静态变量访问

java - 在 Android 中使用 Ada 代码

java - Hibernate 标准优化

java - 在 JSP 上使用 Hibernate

java - HashMap<类<?>, 列表<类<?>>> : specify that the lists' classes extend the keys'

mysql - Spring 与 mySql

c++ - 适合构图的智能指针

java - 没有字段的派生类的 Hibernate 映射

C#泛型接口(interface)和继承