Eclipse+JBoss+EJB3通过继承实体Bean将单个表映射成多个表

开发 后端
本文介绍使用Eclipse+JBoss+EJB3通过继承实体Bean将单个表映射成多个表。如果以前使用过EJB1.x或EJB2.x的实体Bean,会发现无法通过继承实体Bean将单个表分成多表。

如果以前使用过EJB1.x或EJB2.x的实体Bean,会发现无法通过继承实体Bean将单个表分成多表。而在EJB3中,我们很容易实现这个功能。先看看图1所示的表结构和记录。

t_accounts表的结构和记录

图1   t_accounts表的结构和记录

在t_accounts表中,有一个account_type字段。这个字段是一个长度为1的String类型字段。只能取两个值:C和S。如果该字段值为C,表示活期帐户(CheckingAccount),如果该字段值为S,表示储蓄存款帐户(SavingsAccount)。t_accounts表的前三个字段(account_id、balance和account_type)是活期帐户和储蓄存款帐户都需要的,而interestrate只对储蓄存款帐户有意义,overdraftlimit只对活期帐户有意义。因此,我们可以将t_accounts表分成两个表,当account_type的值为C时和S时各为一个表。

如果使用EJB3的实体Bean,可以先编写一个Account类来封装t_accounts的前三个字段,代码如下:

package entity;  
 
import javax.persistence.Column;  
import javax.persistence.DiscriminatorColumn;  
import javax.persistence.Entity;  
import javax.persistence.GeneratedValue;  
import javax.persistence.GenerationType;  
import javax.persistence.Id;  
import javax.persistence.Inheritance;  
import javax.persistence.InheritanceType;  
import javax.persistence.Table;  
 
@Entity 
@Table(name="t_accounts")  
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)  
@DiscriminatorColumn(name="account_type")  
public class Account  
{  
    protected String id;  
    protected float balance;  
    protected String type;  
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY)  
    @Column(name="account_id")  
    public String getId()  
    {  
        return id;  
    }  
    public void setId(String id)  
    {  
        this.id = id;  
    }  
    public float getBalance()  
    {  
        return balance;  
    }  
    public void setBalance(float balance)  
    {  
        this.balance = balance;  
    }  
    @Column(name="account_type",insertable=false, updatable=false)  
    public String getType()  
    {  
        return type;  
    }  
    public void setType(String type)  
    {  
        this.type = type;  
    }  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

对于Account类的代码,要注意如下两个注释:

1. @Inheritance

2. @DiscriminatorColumn

@Inheritance注释用于设置实体Bean的继承类型,默认值是InheritanceType.SINGLE_TABLE,也就是单表策略类型。如果使用该继承类型,每一个从该实体Bean继承的表都会被映射成一个子表。而这个子表需要根据一个鉴别字段的值来映射,在本例中该字段是account_type,这个字段由@DiscriminatorColumn注释来指定。还要注意一点的是,由于account_type字段现在被设置成了鉴别字段,因此,该字段值不能由开发人员通过代码动态指定,而必须在Account类的子类中通过注释来指定(在后面会详细介绍),因此,需要使用@Column注释将该字段对应的实体Bean属性设为不可插件和编辑的(insertable=false, updatable=false)。否则在运行程序时会抛出下面的异常:

org.hibernate.MappingException: Repeated column in mapping for entity: entity.SavingsAccount column: account_type (should be mapped with insert="false" update="false")

活期帐户的实体Bean的代码如下:

package entity;  
 
import javax.persistence.DiscriminatorValue;  
import javax.persistence.Entity;  
 
@Entity 
@DiscriminatorValue("C")  
public class CheckingAccount extends Account  
{  
    private double overdraftLimit;  
 
    public double getOverdraftLimit()  
    {  
        return overdraftLimit;  
    }  
 
    public void setOverdraftLimit(double overdraftLimit)  
    {  
        this.overdraftLimit = overdraftLimit;  
    }  
 
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

在CheckingAccount类中通过@DiscriminatorValue注释将account_type字段的值设为了C。如果使用CheckingAccount类来映射t_accounts表时,EJB容器会自动将t_accounts表的account_type字段值设为C(并不需要开发人员干预)。

储蓄存款帐户对应的实体Bean的代码如下:

package entity;  
 
import javax.persistence.DiscriminatorValue;  
import javax.persistence.Entity;  
 
@Entity 
@DiscriminatorValue("S")  
public class SavingsAccount extends Account  
{  
    private double interestRate;  
 
    public double getInterestRate()  
    {  
        return interestRate;  
    }  
 
    public void setInterestRate(double interestRate)  
    {  
        this.interestRate = interestRate;  
    }  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

可以下面的代码进行测试:

CheckingAccount ca = new CheckingAccount();  
ca.setBalance(342);  
ca.setOverdraftLimit(120);  
em.persist(ca); // 自动将account_type字段的值设为C  
SavingsAccount sa = new SavingsAccount();  
sa.setBalance(200);  
sa.setInterestRate(321);  
em.persist(sa); //  自动将account_type字段的值设为S 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

【编辑推荐】

  1. Eclipse+JBoss+EJB3配置文件发布Session Bean
  2. Eclipse+JBoss+EJB3实现Entity Bean的多对多映射
  3. Eclipse+JBoss+EJB3实现Entity Bean的一对多映射
  4. Eclipse+JBoss+EJB3实现Entity Bean的一对一映射
  5. Eclipse+JBoss+EJB3编写第一个实体Bean程序
责任编辑:book05 来源: BlogJava
相关推荐

2009-06-24 15:59:04

消息驱动Bean

2009-06-24 15:56:47

实体Bean连接策略

2009-06-24 15:47:13

实体Bean

2009-06-24 15:53:08

Entity Bean多对多映射

2009-06-10 11:42:26

Session BeaEclipse+JBo

2009-06-24 15:51:47

Entity Bean一对多映射

2009-06-10 11:09:40

配置文件SessionEclipse+JBo

2009-06-10 12:34:01

Session BeaEclipse+JBo

2009-06-24 15:49:54

Entity Bean一对一映射

2009-06-10 11:36:45

有状态的SessionEclipse+JBo

2009-06-24 15:57:44

JPQL命名查询

2009-06-24 15:58:15

EntityManag

2009-06-24 16:00:00

2009-06-10 12:54:35

无状态的SessionEclipse+JBo

2009-06-17 09:01:20

JBoss访问EJB

2009-06-29 17:07:54

EJB部署Jboss

2009-06-15 16:06:25

JBoss IDE

2009-09-24 12:05:35

2009-06-16 09:05:43

JBoss AS

2009-06-17 08:51:26

Eclipse启动JB
点赞
收藏

51CTO技术栈公众号