一、结构

You can map an entire class hierarchy to a single table. This table includes columns for all properties of all classes in the hierarchy. The value of an extra type discriminator column or formula identifies the concrete subclass represented by a particular row. Figure 6.2 shows this approach.

二、代码

1.

 package org.jpwh.model.inheritance.singletable;

 import org.jpwh.model.Constants;

 import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.validation.constraints.NotNull; @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "BD_TYPE")
public abstract class BillingDetails { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull // Ignored by Hibernate for schema generation!
@Column(nullable = false)
protected String owner; // ... protected BillingDetails() {
} protected BillingDetails(String owner) {
this.owner = owner;
} public Long getId() {
return id;
} public String getOwner() {
return owner;
} public void setOwner(String owner) {
this.owner = owner;
}
}

2.

 package org.jpwh.model.inheritance.singletable;

 import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.validation.constraints.NotNull; @Entity
@DiscriminatorValue("BA")
public class BankAccount extends BillingDetails { @NotNull
protected String account; @NotNull
protected String bankName; @NotNull
protected String swift; public BankAccount() {
super();
} public BankAccount(String owner, String account, String bankName, String swift) {
super(owner);
this.account = account;
this.bankName = bankName;
this.swift = swift;
} public String getAccount() {
return account;
} public void setAccount(String account) {
this.account = account;
} public String getBankName() {
return bankName;
} public void setBankName(String bankName) {
this.bankName = bankName;
} public String getSwift() {
return swift;
} public void setSwift(String swift) {
this.swift = swift;
}
}

3.

 package org.jpwh.model.inheritance.singletable;

 import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.validation.constraints.NotNull; @Entity
@DiscriminatorValue("CC")
public class CreditCard extends BillingDetails { @NotNull // Ignored by Hibernate for DDL generation!
protected String cardNumber; @NotNull
protected String expMonth; @NotNull
protected String expYear; // ... public CreditCard() {
super();
} public CreditCard(String owner, String cardNumber, String expMonth, String expYear) {
super(owner);
this.cardNumber = cardNumber;
this.expMonth = expMonth;
this.expYear = expYear;
} public String getCardNumber() {
return cardNumber;
} public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
} public String getExpMonth() {
return expMonth;
} public void setExpMonth(String expMonth) {
this.expMonth = expMonth;
} public String getExpYear() {
return expYear;
} public void setExpYear(String expYear) {
this.expYear = expYear;
}
}

4.在无法改变表结构增加discriminator的情况下,可以使用Hibernate的扩展注解@DiscriminatorFormula,底层是利用数据库的case when 语句

 package org.jpwh.model.inheritance.singletableformula;

 import org.jpwh.model.Constants;

 import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.validation.constraints.NotNull; @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@org.hibernate.annotations.DiscriminatorFormula(
"case when CARDNUMBER is not null then 'CC' else 'BA' end"
)
public abstract class BillingDetails {
// ...
@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
protected String owner; protected BillingDetails() {
} protected BillingDetails(String owner) {
this.owner = owner;
} public Long getId() {
return id;
} public String getOwner() {
return owner;
} public void setOwner(String owner) {
this.owner = owner;
}
}

三、SINGLE_TABLE的优缺点

1.优点

(1)This mapping strategy is a winner in terms of both performance and simplicity. It’s the best-performing way to represent polymorphism—both polymorphic and non-polymorphic queries perform well—and it’s even easy to write queries by hand. Ad hoc reporting is possible without complex joins or unions. Schema evolution is straightforward.

Hibernate generates the following  SQL for  select bd from BillingDetails bd :

 select
ID, OWNER, EXPMONTH, EXPYEAR, CARDNUMBER,
ACCOUNT, BANKNAME, SWIFT, BD_TYPE
from
BILLINGDETAILS

To query the CreditCard subclass, Hibernate adds a restriction on the discriminator column:

 select
ID, OWNER, EXPMONTH, EXPYEAR, CARDNUMBER
from
BILLINGDETAILS
where
BD_TYPE='CC'

2.缺点

(1)the loss of NOT NULL constraints may be a serious problem from the point of view of data correctness. Imagine that an expiration date for credit cards is required, but your database schema can’t enforce this rule because all columns of the table can be NULL .

(2)Another important issue is normalization. You’ve created functional dependencies between non-key columns, violating the third normal form. As always, denormalization for performance reasons can be misleading, because it sacrifices long-term stability,maintainability, and the integrity of data for immediate gains that may be also achieved
by proper optimization of the SQL execution plans (in other words, ask your DBA ).

(3)considering denormalized schemas can become a major burden in the long term. Your DBA may not like it at all

(4)An implementation quirk of Hibernate requires that you declare nullability with @Column because Hibernate
ignores Bean Validation’s @NotNull when it generates the database schema.Hibernate ignores the @NotNull for schema DDL generation, but it observes it at runtime, before inserting a row.

JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-004Table per class hierarchy(@Inheritance..SINGLE_TABLE)、@DiscriminatorColumn、@DiscriminatorValue、@DiscriminatorFormula)的更多相关文章

  1. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-005Table per subclass with joins(@Inheritance(strategy = InheritanceType.JOINED)、@PrimaryKeyJoinColumn、)

    一.结构 The fourth option is to represent inheritance relationships as SQL foreign key associations. Ev ...

  2. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-008Polymorphic many-to-one associations(@ManyToOne、@Inheritance、)

    一.结构 二.代码 1. package org.jpwh.model.inheritance.associations.manytoone; import org.jpwh.model.Consta ...

  3. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-006Mixing inheritance strategies(@SecondaryTable、@PrimaryKeyJoinColumn、<join fetch="select">)

    一.结构 For example, you can map a class hierarchy to a single table, but, for a particular subclass, s ...

  4. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-003Table per concrete class with unions(@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)、<union-subclass>)

    一.代码 1. package org.jpwh.model.inheritance.tableperclass; import org.jpwh.model.Constants; import ja ...

  5. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-002Table per concrete class with implicit polymorphism(@MappedSuperclass、@AttributeOverride)

    一.结构 二.代码 1. package org.jpwh.model.inheritance.mappedsuperclass; import javax.persistence.MappedSup ...

  6. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-001Hibernate映射继承的方法

    There are four different strategies for representing an inheritance hierarchy: Use one table per co ...

  7. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-009Polymorphic collections(@OneToMany(mappedBy = "user")、@ManyToOne、)

    一.代码 1. package org.jpwh.model.inheritance.associations.onetomany; import org.jpwh.model.Constants; ...

  8. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-007Inheritance of embeddable classes(@MappedSuperclass、@Embeddable、@AttributeOverrides、、)

    一.结构 二.代码 1. package org.jpwh.model.inheritance.embeddable; import javax.persistence.MappedSuperclas ...

  9. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-007UserTypes的用法(@org.hibernate.annotations.Type、@org.hibernate.annotations.TypeDefs、CompositeUserType、DynamicParameterizedType、、、)

    一.结构 二.Hibernate支持的UserTypes接口  UserType —You can transform values by interacting with the plain JD ...

随机推荐

  1. L117

    Hoover has become a household word for a vacuum cleaner through the world.Economics are slowly killi ...

  2. Requests 库

    Requests 库的两个重要的对象:(Request , Response) Response对象的属性: import requests r =requests.get('http://www.b ...

  3. localtime 和 localtime_r 的区别

    转自:http://blog.csdn.net/maocl1983/article/details/6221810 #include <cstdlib> #include <iost ...

  4. 浅学soap--------2

    使用wsdl文件: 生成wsdl <?php require('person.class.php'); // 引入生成wsdl的类文件 require('SoapDiscovery.class. ...

  5. GO语言list剖析

    GO语言list剖析 本节内容 使用方法 list提供的方法 源码剖析 1. 使用方法 在GO语言的标准库中,提供了一个container包,这个包中提供了三种数据类型,就是heap,list和rin ...

  6. 系列文章--C#即时通讯开发

    对使用UDP协议和大规模即时通讯的思考   C#[Fox即时通讯核心] 开发记录之五 (客户端界面基窗体基本完成)  C#[Fox即时通讯核心] 开发记录之四(服务端多线程异步处理数据 主程序大致结构 ...

  7. bzoj 3160 万径人踪灭——FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...

  8. 动态规划算法(后附常见动态规划为题及Java代码实现)

    一.基本概念 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划. 二.基本思想与策略 基本 ...

  9. Bug:DataGridCell的显示不完整

    最近在使用DataGrid时遇到一个bug, 在客户机器上DataGrid的内容显示不完整, 具体表现为某些列的显示为空. 具体的可视树为:DataGridCell > ContentPrese ...

  10. testng监听ISuiteListener

    实现ISuiteListener public class TestNgBeforeAction implements ISuiteListener{ public void onStart(ISui ...