简体   繁体   English

JPA复合键@OneToMany

[英]JPA composite key @OneToMany

I have the following existing DB schema, which I'd like to recreate with Java and plain JPA annotations (using hibernate as provider, so hibernate specific annotations would work as a last resort):我有以下现有的 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)                         
);

I've thus created the following classes and annotations:因此,我创建了以下类和注释:

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;
}

I left out columnName attributes and other attributes of the entities here.我在这里省略了实体的columnName属性和其他属性。
It does however not quite work as intended.然而,它并没有像预期的那样工作。 If I do not specify a mappedBy attribute for User.userdata , hibernate will automatically create a table USERS_USERS_USERDATA, but as far as I've seen does not use it.如果我不指定User.userdata一个的mappedBy属性,Hibernate会自动创建一个表USERS_USERS_USERDATA,但据我见过不使用它。 It does however use the table which I specified for the Userdata class.然而,它确实使用了我为Userdata类指定的表。

Since I'm rather new to Java and hibernate as well, all I do to test this currently is looking at the DB schema hibernate creates when persisting a few sample entries.由于我对 Java 和 hibernate 也很陌生,因此我目前所做的所有测试都是查看 hibernate 在保留一些示例条目时创建的 DB 模式。

As a result, I'm entirely puzzled as to whether I'm doing this the right way at all.结果,我完全不知道我是否以正确的方式做这件事。 I read the hibernate documentation and quite a bunch of Google results, but none of them seemed to deal with what I want to do (composite key with "subclasses" with their own primary key).我阅读了 hibernate 文档和相当多的 Google 结果,但它们似乎都没有处理我想要做的事情(带有“子类”的复合键和它们自己的主键)。

The mappedBy attribute is mandatory at one of the sides of every bidirectional association.在每个双向关联的一侧, mappedBy属性是强制性的。 When the association is a one-to-many, the mappedBy attribute is placed ot the one- side (ie on the User 's userdata field in your case).当关联是一对多时, mappedBy属性放置在一侧(即在您的情况下,在Useruserdata字段上)。

That's because when an association is bidirectional, one side of the association is always the inverse of the other, so there's no need to tell twice to Hibernate how the association is mapped (ie which join column or join table to use).这是因为当关联是双向的时,关联的一侧总是与另一侧相反,因此不需要两次告诉 Hibernate 关联是如何映射的(即使用哪个连接列或连接表)。

If you're ready to recreate the schema, I would do it right (and easier), and use a surrogate auto-generated key in users_userdata rather than a composite one.如果您准备好重新创建架构,我会做得对(而且更容易),并在 users_userdata 中使用代理自动生成的键,而不是复合键。 This will be much easier to handle, in all the layers of your application.在应用程序的所有层中,这将更容易处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM