我有一个关于Hibernate注释和继承的问题。
在数据库中,我有一个parent
表和一个child
表。 parent
表具有未在child
表中复制的列(Hibernate中的joined
关系)。对于child
表中的每一行,parent
表中都有一行。在这种情况下,child
表中的行和parent
表中的相应行具有相同的id
值。但是,parent
表的行在child
表中没有对应的行。
通过在child
和child
之间建立联接来表示具体的parent
实体,并且具体的parent
仅由表{{1}表示}。
表示这种情况的面向对象的方法是:
parent
类:
parent
@Entity
@Table(name = "Parent")
@Inheritance(strategy = InheritanceType.JOINED)
public class Parent{
@Id
@GeneratedValue
@Column(name = "id")
private int id;
// More properties
}
类:
child
当我使用@Entity
@Table(name = "Child")
@PrimaryKeyJoinColumn(name="id")
public class Child extends Parent{
// More properties
}
列出所有孩子时,每个人都顺利进行。但是,我的问题是,当我尝试使用List child = session.createQuery("FROM Child").list();
列出父项时,它会返回List parent = session.createQuery("FROM Parent").list();
个对象的列表。
有没有办法在Hibernate中表示“可选”继承?
答案 0 :(得分:3)
当您从JPA继承结构直接查找父实体时,“最底层”子实体由JPA实现确定,因为这些子实体需要持久保存在持久区域中。因此,您提到的“可选继承”在JPA中是不可能的。 请参阅Hibernate Inheritance Strategy and Why
的答案在您的情况下,始终应用LEFT OUTER JOIN。你能做什么:
由于继承,您可以将结果转换为父实体。您将获得预期的结果,但由于不必要的连接而具有性能OVERHEAD。
另一个选择是不使用继承。除此之外,您可以使用单向一对一关系,其中子将外键 id 添加到父。在此模型中,您可以使用父级(使用CascadeType.ALL)处理子级,并在不加入的情况下单独查询父级。一个例子:http://www.java2s.com/Tutorial/Java/0355__JPA/OneToOneUnidirectional.htm
答案 1 :(得分:1)
父表包含未在子表中复制的列(Hibernate中的连接关系)
如果子表应该是父表的子类,那么这对你真的有意义吗?子类应该包含超类中的所有内容,可能还有更多内容。
我认为你真正想要建模的是这样的:
@Entity
@Table(name = "Parent")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Parent {
@Id
@GeneratedValue
@Column(name = "id")
private int id;
// More properties
}
@Entity
@Table(name = "Child")
@PrimaryKeyJoinColumn(name="id")
public class Child extends Parent {
// More properties
}
@Entity
@Table(name = "ConcreteParent")
@PrimaryKeyJoinColumn(name="id")
public class ConcreteParent extends Parent {
// More properties
}
所有共享属性都在Parent
中,ConcreteParent
将包含您想要放在父表中的所有其他列。
如果您希望父表与子表没有任何不同的属性,并且子表可能有更多属性,您仍然可以使用此方法。
话虽如此,请看一下类似问题的答案:Hibernate: Change instance of base class to subclass。
问题是,如果您尝试使用继承向现有事物添加功能,那么您的模型可能是错误的。继承对于区分具有共同属性的不同事物非常有用。