Hibernate和继承

时间:2012-07-31 11:34:26

标签: hibernate inheritance

我有两张表文字并且固有 TextUser

文字包含:id,textType
TextUser 包含:id,locale,name,title

TextUser.id Text.id 的外键。所以加入的例子是:

Text.id - Text.textType - TextUser.id - TextUser.locale - TextUser.name

100          1            100          en            name1
100          1            100          fr            name2
101          1            101          en            name3

因此,在密钥100中,我们在Text中有一条记录,两条记录具有相同的id但在TextUser中具有不同的区域设置(en,fr)。

这是遗留系统,所以我无法修改结构。现在我正在尝试用hibernate处理它。

@Entity(name = "Text")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Text {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "TextId")
    private Long id;

    @Column(name = "TextType")
    private Integer textType;

    @Entity
    @Table(name = "TextUser")
    @ForeignKey(name = "FK_TextUser_Text")
    public class TextUser extends Text {

        @Column(name = "locale")
        private String locale;

        @Column(name = "name")
        private String name;

因此它适用于一个语言环境。但是如何使用键100插入新值,但是新的语言环境?我们在Text中有ID,而hibernate将它用于外键TextUser.id。因此,如果我设置了显式id但不同的语言环境,我将得到“org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已经与会话相关联”

2 个答案:

答案 0 :(得分:1)

这不是继承的有效案例。

您应该将其建模为一个复合键(TextUser有一个复合键(idlocale),对吗?)和多对一的派生身份识别(从那时起) TextUser的复合键包含外键。

@MapsId javadoc中显示了一种可能的方法。

答案 1 :(得分:0)

您将无法使用继承关系映射这些类,因为父表上的ID将被复制(这是您目前得到的错误)。

您需要将这两个类映射为一对多关系(它们是)。 Text类将保持原样(@Inheritance除外),UserText将在UserText.id和UserText.locale之间具有复合ID。

如果您不需要更新这些表,则可以使用两个表的连接创建视图(Text.id - Text.textType - TextUser.locale - TextUser.name)并使用复合ID:Text。 id和TextUser.locale。