JPA继承
您好,我是 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 对象尚未持久化时,Apple 对象才会持久化。
如果我尝试用已经持久化的 Fruit 对象来持久化一个 apple 对象:
Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);
我会收到一个错误,因为 JPA 尝试在 Fruit 表上创建一个 Id="1" 的新行 这已经存在了。
..
Hi I'm new to JPA and I'm having trouble understanding how it handles inheritance.
I have a specific problem I need solved without changing the DB scheme, but if you can't find a solution I would appreciate solution suggestions with a different DB scheme (Hibernate/TopLink solutions welcome).
If I was unclear or you need more information, please tell me so. Thanks in advance!
I have this database:
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)
So far my entities look like this :
@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;
}
Currently I am able to persist Fruit objects without a problem..
Apple objects persist only when their Fruit object hasn't been persisted yet.
If I try to persist an apple object with an already persisted Fruit object :
Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);
I will get an error since JPA tries to create a new row on Fruit table with Id="1"
which already exists.
..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当使用 JPA 持久化子对象(即您的情况下的
provider.create(apple1)
)时,一条记录将被插入到子表及其所有父表中。因此provider.create(apple1)
将向 Fruit 表插入一条记录,向 Apple 表插入一条记录。在您的示例中,如果您只想保留一个 apple 对象,只需调用
provider.create(apple1)
就足够了。它也会将水果引用保留在苹果对象中。BTW,我建议Fruit Table的PK为数字类型,并使用
@GeneeratedValue
来标记Fruit bean的ID字段。这样,你就可以让数据库为你生成一个ID,而不再需要在java代码中显式设置它,以避免因为在java代码中设置一个已经存在的ID而出现“ID已存在错误”。When using JPA to persist a child object (i.e
provider.create(apple1)
in your case) , a record will be inserted to the child table and all of its parent tables. Soprovider.create(apple1)
will insert a record to the Fruit and a record to the Apple table.In your example , if you only want to persist an apple object ,just call
provider.create(apple1)
is enough . It will persist the fruit reference inside the apple object too.BTW , I suggest the Fruit Table 's PK to be a number type , and uses
@GeneratedValue
to mark the ID field of the Fruit bean. In this way , you can let the database to generate an ID for you and no longer need to set it explicitly in the java code to avoid this "ID already exist error" because of setting an already existing ID in the java code.我认为这完全按照设计进行。当您使用联合继承并持久保存一个苹果对象时,JPA 将自动插入到苹果表和水果表中。您不需要在实体类中对附加关系或 JoinColumn 进行建模。
I think this is working exactly as designed. When you use joined inheritance and persist an apple object, JPA will automatically insert into both the apple and fruit tables. You don't need to model an additional relation or JoinColumn in your entity classes.
您尝试在创建数据库表时使用java继承概念,这在这种情况下有点不可能。我可以想出一种不同的方法来解决这个问题。有表fruit_type和水果。
Fruit_type(id,类型名称,desc)
Fruit(id, name, type_id, desc) 这里 type_id 将是外键。
You are trying to use java inheritance concept while creating the db tables, which is somewhat not possible in this case. I could think one different approach for this problem. Have table fruit_type and fruit.
fruit_type(id, typename,desc)
fruit(id, name, type_id, desc) here type_id will be the foreign key.
我有同样的问题,到目前为止,我发现的唯一方法是查询父级并用父级构造子级。然后删除父记录并重新创建两条记录。
I have the same issue and so far the only way I found was to query the parent and construct child with parent. Then remove parent and recreate both records.