何时在 hibernate 中使用 DiscriminatorValue 注解
Posted
技术标签:
【中文标题】何时在 hibernate 中使用 DiscriminatorValue 注解【英文标题】:When to use DiscriminatorValue annotation in hibernate 【发布时间】:2013-05-22 06:18:15 【问题描述】:在 hibernate 中使用 DiscriminatorValue 注解的最佳场景和时间是什么时候?
【问题讨论】:
你有没有试过看文档,可以参考docs.jboss.org/hibernate/stable/annotations/reference/en/… & docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/… 【参考方案1】:这两个链接最能帮助我理解继承概念:
http://docs.oracle.com/javaee/6/tutorial/doc/bnbqn.html
http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa1.html?page=6
要了解判别器,首先必须了解继承策略:SINGLE_TABLE、JOINED、TABLE_PER_CLASS。
判别器常用于 SINGLE_TABLE 继承,因为您需要一列来标识记录的类型。
示例:您有一个 Student 类和 2 个子类:GoodStudent 和 BadStudent。 Good 和 BadStudent 数据都将存储在 1 个表中,但是我们当然需要知道类型,这就是 (DiscriminatorColumn 和) DiscriminatorValue 会出现的时间。
注释学生类
@Entity
@Table(name ="Student")
@Inheritance(strategy=SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING,
name = "Student_Type")
public class Student
private int id;
private String name;
坏学生班
@Entity
@DiscriminatorValue("Bad Student")
public class BadStudent extends Student
//code here
好学生班
@Entity
@DiscriminatorValue("Good Student")
public class GoodStudent extends Student
//code here
所以现在 Student 表将有一个名为 Student_Type 的列,并将在其中保存 Student 的 DiscriminatorValue。
-----------------------
id|Student_Type || Name |
--|---------------------|
1 |Good Student || Ravi |
2 |Bad Student || Sham |
-----------------------
查看我上面发布的链接。
【讨论】:
【参考方案2】:让我用一个例子给你解释一下。假设您有一个名为 Animal 的类,在 Animal 类下有许多子类,如 Reptile、Bird ...等。
在数据库中,您有一个名为 ANIMAL
的表
---------------------------
ID||NAME ||TYPE ||
---------------------------
1 ||Crocodile ||REPTILE ||
---------------------------
2 ||Dinosaur ||REPTILE ||
---------------------------
3 ||Lizard ||REPTILE ||
---------------------------
4 ||Owl ||BIRD ||
---------------------------
5 ||parrot ||BIRD ||
---------------------------
这里 TYPE
列称为 DiscriminatorColumn ,因为该列包含明确区分爬行动物和鸟类的数据。而TYPE
列中的数据REPTILE
和BIRD
就是DiscriminatorValue。
所以在java部分这个结构看起来像:
动物类:
@Getter
@Setter
@Table(name = "ANIMAL")
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "TYPE")
public class Animal
@Id
@Column(name = "ID")
private String id;
@Column(name = "NAME")
private String name;
爬虫类:
@Entity
@DiscriminatorValue("REPTILE")
public class Reptile extends Animal
鸟类:
@Entity
@DiscriminatorValue("BIRD")
public class Bird extends Animal
【讨论】:
【参考方案3】:当您使用单表策略进行实体继承,并且您希望鉴别器列的值不是实体具体类的类名时,或者当鉴别器列的类型不是时字符串。
在the javadoc 中举例说明了这一点。
【讨论】:
Java 7 Javadoc 声明 DiscriminatorColumn 可以被 JOINED 策略和单表使用。 docs.oracle.com/javaee/7/api/javax/persistence/…【参考方案4】:这是每个类层次结构的休眠表的解释和一个示例,假设我们有名为 Payment 的基类和 2 个派生类,如 CreditCard、Cheque
如果我们保存派生类对象,如 CreditCard 或 Check,那么 Payment 类对象也会自动保存到数据库中,并且在数据库中,所有数据将仅存储在单个表中,该表肯定是基类表.
但是这里我们必须在数据库中使用一个额外的鉴别器列,只是为了识别表中保存了哪个派生类对象以及基类对象,如果我们不使用该列,hibernate会抛出异常
【讨论】:
以上是关于何时在 hibernate 中使用 DiscriminatorValue 注解的主要内容,如果未能解决你的问题,请参考以下文章
何时使用 Spring JPA (Hibernate) Entity Manager 将连接返回到连接池?
hibernate.hbm2ddl.auto Hibernate 如何决定何时创建或更新 ddl?
元素类型为 "resultMap" 的内容必须匹配 "(constructor?,id*,result*,association*,collection*,discrim