1

我有两个表Text和继承的 TextUser

文本包含:id、textType
TextUser包含:id、语言环境、名称、标题

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 中有一条记录,在 TextUser 中有两条具有相同 id 但不同语言环境(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:具有相同标识符值的不同对象已与会话关联”

4

2 回答 2

1

这不是继承的有效案例。

您应该将其建模为复合键(TextUser具有复合键 ( id, locale),对吗?)和具有派生身份的多对一关系(因为复合键TextUser包含外键)。

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

于 2012-07-31T11:47:03.710 回答
0

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

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

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

于 2012-07-31T11:46:37.330 回答