我有两张表文字并且固有 TextUser 。
文字包含:id,textType
TextUser 包含:id,locale,name,title
TextUser.id 是 Text.id 的外键。所以加入的例子是:
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:具有相同标识符值的另一个对象已经与会话相关联”
答案 0 :(得分:1)
这不是继承的有效案例。
您应该将其建模为一个复合键(TextUser
有一个复合键(id
,locale
),对吗?)和多对一的派生身份识别(从那时起) 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。