JPA复合键@OneToMany

时间:2011-09-27 13:11:40

标签: java hibernate jpa composite-key

我有以下现有的DB模式,我想用Java和普通的JPA注释重新创建(使用hibernate作为提供者,因此hibernate特定的注释将作为最后的手段):

CREATE TABLE users (
    user_id NUMBER NOT NULL                     -- pk
);

CREATE TABLE userdata_keys (
    userdata_key_id NUMBER NOT NULL,            -- pk
    key VARCHAR2(128) NOT NULL                  
);

CREATE TABLE users_userdata (
    user_id NUMBER NOT NULL,                    -- fk users.user_id
    userdata_key_id NUMBER NOT NULL,            -- fk userdata_keys.userdata_key_id 
    value VARCHAR2(256)                         
);

因此我创建了以下类和注释:

class User {
    @Id
    Long id;
    @OneToMany
    Set<Userdata> userdata;
}

class UserdataKey {
    @Id
    Long id;
    String key;
}

class Userdata {
    String value;
    @EmbeddedId
    UserdataId userdataId;
}

@Embeddable
class UserdataId {
    User user;
    UserdataKey userdataKey;
}

我在这里遗漏了 columnName 属性和实体的其他属性 然而,它确实没有按预期工作。 如果我没有为 User.userdata 指定 mappedBy 属性,hibernate将自动创建一个表USERS_USERS_USERDATA,但据我所见,不使用它。但它确实使用了我为 Userdata 类指定的表。

由于我对Java和hibernate也很陌生,所以我目前所做的就是查看hibernate在持久保存一些示例条目时创建的数据库模式。

结果,我完全不知道我是否正确地做到了这一点。我阅读了hibernate文档和相当多的Google结果,但是它们似乎都没有处理我想要做的事情(使用自己的主键复合键“子类”)。

2 个答案:

答案 0 :(得分:3)

mappedBy属性在每个双向关联的一侧是必需的。当关联是一对多时,mappedBy属性被放置在单侧(即在您的案例中User的{​​{1}}字段上)。

这是因为当关联是双向的时,关联的一端总是与另一端相反,所以不需要告诉Hibernate两次关联是如何映射的(即使用哪个连接列或连接表)。

如果您已准备好重新创建架构,我会做得对(并且更容易),并在users_userdata中使用代理自动生成的密钥而不是复合密钥。在应用程序的所有层中,这将更容易处理。

答案 1 :(得分:0)

最近,我使用复合主键创建了“多对多”。

Mapping ManyToMany with composite Primary key and Annotation:

将其改为一对多不应该是一个大问题。