honzeland

记录点滴。。。

常用链接

统计

Famous Websites

Java

Linux

P2P

最新评论

Hibernate Annotations

Use one single table "blank_fields" for both A and B. "blank_fields" has fields: 'ref_id', 'blank_field', 'type'. 'type' is used to identify which entity the record belongs to. Use 'type' + 'ref_id' to specify the collection of elements for one entity.

@Entity
@Table(name 
= "table_a")
public class A {
    
private Set<BlankField> blankFields = new HashSet<BlankField>();
   
    @CollectionOfElements
    @Fetch(FetchMode.SUBSELECT)
    @Enumerated(EnumType.ORDINAL)
    @JoinTable(name 
= "blank_fields", joinColumns = { @JoinColumn(name = "ref_id") })
    @Cascade(value 
= org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    @Column(name 
= "blank_field", nullable = false)
    @SQLInsert(sql 
= "INSERT INTO blank_fields(ref_id, blank_field, type) VALUES(?,?,0)")
    @Where(clause 
= "type=0")
    
public Set<BlankField> getBlankFields() { // BlankField is an enum
        
return blankFields;
    }

    @SuppressWarnings(
"unused")
    
private void setBlankFields(Set<BlankField> blankFields) {
        
this.blankFields = blankFields;
    }
// End B

@Entity
@Table(name 
= "table_b")
public class B {
    
private Set<BlankField> blankFields = new HashSet<BlankField>();
   
    @CollectionOfElements
    @Fetch(FetchMode.SUBSELECT)
    @Enumerated(EnumType.ORDINAL)
    @JoinTable(name 
= "blank_fields", joinColumns = { @JoinColumn(name = "ref_id") })
    @Cascade(value 
= org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    @Column(name 
= "blank_field", nullable = false)
    @SQLInsert(sql 
= "INSERT INTO blank_fields(ref_id, blank_field, type) VALUES(?,?,1)"// used for insert
    @Where(clause = "type=1"// used for query, if not @CollectionOfElements, such as @OneToMany, use @WhereJoinTable instead
    public Set<BlankField> getBlankFields() {
        
return blankFields;
    }

    @SuppressWarnings(
"unused")
    
private void setBlankFields(Set<BlankField> blankFields) {
        
this.blankFields = blankFields;
    }
}

当然还有其他的方式来实现上面的需求,上面采用的单表来记录不同实体的associations(这儿是CollectionOfElements,并且返回的是Set<Enum>,不是Set<Embeddable>),然后用'type'来区分不同的实体,这样做的好处是:数据库冗余少,易于扩展,对于新的实体,只需加一个type值,而不需更改数据库表结构。另外一种采用单表的方式是为每个实体增加新的字段,如
"blank_fields": 'a_id', 'b_id', 'blank_field', a_id reference table_a (id), b_id reference table_b (id). 这样在映射的时候更简单,
对于A,映射为
@JoinTable(name = "blank_fields", joinColumns = { @JoinColumn(name = "a_id") })
对于B,映射为
@JoinTable(name = "blank_fields", joinColumns = { @JoinColumn(name = "b_id") })
这样作的缺点是:带来了数据库冗余,对于blank_fields来讲,任一条记录,a_id和b_id中只有一个不为null。当多个实体共用这个表时,用上面的方法更合理,如果共用实体不多时,这种方法更方便。

posted on 2010-04-20 17:20 honzeland 阅读(444) 评论(0)  编辑  收藏 所属分类: Hibernate


只有注册用户登录后才能发表评论。


网站导航: