0

考虑下表结构

country
=======
id
code
name_id

label
======
id
code
label_value_id

translations
=============
id
ref_id
language
value

现在我需要找到一个 JPA 映射来映射country:name_idlabel:label_value_id翻译ref_id。我一直在搜索正确的英语术语来解释这种情况,但在体面的点击中却一无所获。所以数据库可以像这个例子一样保存记录

country
id: 1, code: BE, name_id: 30

label
id: 1, code: LABELA, label_value_id: 31

translations
id: 1, ref_id: 30, language: EN, value: BELGIUM
id: 2, ref_id: 30, language: NL, value: BELGIE
id: 3, ref_id: 31, language: EN, value: ALPHA_A
id: 4, ref_id: 31, language: NL, value: ALFA_A

在 Java 中,我有 3 个类

Country、Label 和 Translation 我将@OneToMany在 Country 和 Label 与 Translation 建立关系,两者都应该映射,ref_id但我不知道如何编写@OneToMany代码来实现这一点。任何正确方向的提示将不胜感激,提供解决方案或手册

=====

2013-03-23 更新

正如 Joop 所说,使用鉴别器是解决方案,但它并不是开箱即用的。我被迫使用休眠注释@DiscriminatorOptions(force=true)。如果你不添加它,hibernate 在获取所需的集合时会完全忽略它的 SQL 查询中的鉴别器。

@Entity
@Table(name = "testtranslations")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force=true)
public class TestTranslation extends DomainObject {

    /**
     * 
     */
    private static final long serialVersionUID = -6211853644196769521L;

    private long id;
    private String language;
    private String value;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="testtranslations_seq_gen") 
    @SequenceGenerator(name="testtranslations_seq_gen", sequenceName="TESTTRANSLATIONS_SEQ") 
    @Column(name="testtranslation_id")
    public long getId() {
        return id;
    }

    @Column(name="language", length=3, nullable=false)
    public String getLanguage() {
        return language;
    }

    @Column(name="value")
    public String getValue() {
        return value;
    }

    @Override
    public void setId(long id) {
        this.id = id;
    }

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

    public void setValue(String value) {
        this.value = value;
    }
}


@Entity
@Table(name = "testcountries")
public class TestCountry extends DomainObject {

    /**
     * 
     */
    private static final long serialVersionUID = -9207081478447113501L;

    private long id;
    private String code;
    private List<NameTranslation> name;
    private List<DescriptionTranslation> description;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="testcountries_seq_gen") 
    @SequenceGenerator(name="testcountries_seq_gen", sequenceName="TESTCOUNTRIES_SEQ") 
    @Column(name="country_id")
    public long getId() {
        return id;
    }

    @Column(name="iso_code", length=3, nullable=false)
    public String getCode() {
        return code;
    }

    @OneToMany(mappedBy="refId")
    public List<NameTranslation> getName() {
        return name;
    }

    @OneToMany(mappedBy="refId")
    public List<DescriptionTranslation> getDescription() {
        return description;
    }

    @Override
    public void setId(long id) {
        this.id = id;
    }

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

    public void setName(List<NameTranslation> name) {
        this.name = name;
    }

    public void setDescription(List<DescriptionTranslation> description) {
        this.description = description;
    }
}

@Entity
@DiscriminatorValue("NAMETRANSLATION")
public class NameTranslation extends TestTranslation {

    /**
     * 
     */
    private static final long serialVersionUID = 7197732491071768673L;

    private TestCountry refId;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "refId", nullable=false)
    public TestCountry getRefId() {
        return refId;
    }

    public void setRefId(TestCountry refId) {
        this.refId = refId;
    }   
}

@Entity
@DiscriminatorValue("DESCTRANSLATION")
public class DescriptionTranslation extends TestTranslation {

    /**
     * 
     */
    private static final long serialVersionUID = -4128287237786410515L;

    private TestCountry refId;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "refId", nullable=false)
    public TestCountry getRefId() {
        return refId;
    }

    public void setRefId(TestCountry refId) {
        this.refId = refId;
    }   
}

我进行了所需的休眠映射并编写了一个 DbUnit 测试以通过 id 加载带有以下数据的 TestCountry

<TESTCOUNTRIES COUNTRY_ID="1" VERSION="0" ISO_CODE="BE" />  
<TESTTRANSLATIONS TESTTRANSLATION_ID="1" VERSION="0" LANGUAGE="EN" VALUE="Belgium" REFID="1" DTYPE="NAMETRANSLATION" />
<TESTTRANSLATIONS TESTTRANSLATION_ID="2" VERSION="0" LANGUAGE="NL" VALUE="Belgie" REFID="1" DTYPE="NAMETRANSLATION" />
<TESTTRANSLATIONS TESTTRANSLATION_ID="3" VERSION="0" LANGUAGE="EN" VALUE="BelgiumDesc" REFID="1" DTYPE="DESCTRANSLATION" />
<TESTTRANSLATIONS TESTTRANSLATION_ID="4" VERSION="0" LANGUAGE="NL" VALUE="BelgieDesc" REFID="1" DTYPE="DESCTRANSLATION" />

我希望这将在未来对其他人有所帮助,我很遗憾没有 JPA 解决方案,我不得不被迫使用休眠注释。

4

1 回答 1

1

有点困难,因为您有表 1 或表 2 的外键。

JPA中确实存在一个鉴别器概念,用于表继承。然后从一个公共抽象表中派生出两个表,并具有不同的鉴别器字段。一个例子。不过,这有点不同。

PS 使用搜索键 discriminatorValue 和 discriminatorColumn 寻找更好的示例。

于 2013-03-21T15:11:40.570 回答