JPA Discriminator SINGLE_TABLE继承

时间:2012-08-18 10:47:52

标签: java jpa annotations

我有一个带有三个子表Sub1,Sub2和Sub3的HeaderTable。 Sub1和Sub2需要引用HeaderTable中的相同行数据,而Sub3需要引用另一行数据。

我所做的是创建一个abstractHeader,然后通过头部HeaderTableA和HeaderTableB的两个实现进行扩展。

HeaderTableA有一个Sub1和Sub2列表,而HeaderTableB有Sub3列表。

HeaderTable中的discriminator列是messageType,然后在HeaderTableA上设置为鉴别值“WO”,在HeaderTableB上设置为“CO”。

持久化HeaderTableB(CASCADE.ALL到Sub3)没有问题,因为它只包含一个列表。 当我尝试持久化HeaderTableA时,会出现问题,其中sub1和list sub2的列表都有数据。 但是如果只填充了sub1或sub2列表的列表,那么它也会毫无问题地存在。

遇到的错误坚持外键ID(headerID)不存在。

这样的事情:

@Entity
@Table(name="CODE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING, name="codeType")
@DiscriminatorValue(value="UNKNOWN")
public abstract class BusinessCode extends DateExpirableWithId<Long> {

    private static final long serialVersionUID = -2766041951015641149L;

    private String code;

    @Column(updatable=false, insertable=false)
    private String codeType;

    private String language;

    private String description;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getCodeType() {
        return codeType;
    }

    public void setCodeType(String codeType) {
        this.codeType = codeType;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("BusinessCode [code=");
        builder.append(code);
        builder.append(", codeType=");
        builder.append(codeType);
        builder.append(", language=");
        builder.append(language);
        builder.append(", description=");
        builder.append(description);
        builder.append("]");
        return builder.toString();
    }
}


@Entity
@DiscriminatorValue(value="CountryCode")
public class CountryCode extends BusinessCode {

    private static final long serialVersionUID = -7207238725104662784L;

    private List<SubProperty1> subProperties1;
    private List<SubProperty2> subProperties2;

    public List<SubProperty1> getSubProperties1() {
        return subProperties1;
    }

    public void setSubProperties1(List<SubProperty1> subProperties1) {
        this.subProperties1 = subProperties1;
    }

    public List<SubProperty2> getSubProperties2() {
        return subProperties2;
    }

    public void setSubProperties2(List<SubProperty2> subProperties2) {
        this.subProperties2 = subProperties2;
    }
}

有关表结构的更好描述,请参阅下图: enter image description here

1 个答案:

答案 0 :(得分:2)

我认为这听起来更像是InheritanceType.JOINED。您不需要JOINED策略的鉴别器。

BusinessCode.java(假设您的超类具有ID列等。)

@Entity
@Table(name="CODE")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class BusinessCode extends DateExpirableWithId<Long> {

    private static final long serialVersionUID = -2766041951015641149L;

    @Column(nullable = false)
    private String code;

    @Column(nullable = false)
    private String language;

    @Column(nullable = false)
    private String description;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

CountryCode.java

@Entity
@Table(name="COUNTRY_CODE")
@Inheritance(strategy = InheritanceType.JOINED)
public class CountryCode extends BusinessCode {
  @Column
  private String countryName;

  public String getCountryName() { return countryName; }
  public String setCountryName(String value) { countryName = value; }
}

DepartmentCode.java

@Entity
@Table(name="DEPARTMENT_CODE")
@Inheritance(strategy = InheritanceType.JOINED)
public class DepartmentCode extends BusinessCode {
  @Column
  private String departmentName;

  public String getDepartmentName() { return departmentName; }
  public String setDepartmentName(String value) { departmentName= value; }
}

您的表格结构如下所示:

BUSINESS_CODE
  ID(PK)
  CODE,
  LANGUAGE,
  DESCRIPTION

COUNTRY_CODE
  ID(FK), 
  COUNTRYNAME

DEPARTMENT_CODE
  ID(FK)
  DEPARTMENTNAME

数据看起来像这样:

BUSINESS_CODE
1, "AU","EN","australia country code in english"
2, "AU","FR","australia country code in french"
3, "FIN","EN","finance department code"

COUNTRY_CODE
1, "Australia"
2, "Australie"

DEPARTMENT_CODE
3, "Bean Counters"