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。当多个实体共用这个表时,用上面的方法更合理,如果共用实体不多时,这种方法更方便。