JPA复合键@OneToMany [英] JPA composite key @OneToMany

查看:146
本文介绍了JPA复合键@OneToMany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下现有的数据库模式,我想用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>用户数据;
}

class UserdataKey {
@Id
Long id;
字符串键;
}

类用户数据{
字符串值;
@EmbeddedId
UserdataId userdataId;
}

@Embeddable
class UserdataId {
用户用户;
UserdataKey userdataKey;
}

我忽略了 columnName 属性和其他属性这里的实体。

然而,它并不像预期的那样工作。 如果我没有为 User.userdata 指定 mappedBy 属性,hibernate会自动创建一个表USERS_USERS_USERDATA,但据我所见,不会使用它。它确实使用了我为 Userdata 类指定的表。



由于我对Java和hibernate同样,我目前测试的所有内容都是查看hibernate在持久化示例条目时创建的数据库模式。



因此,我完全迷惑了我是否正确地做这件事。我阅读了hibernate文档以及相当多的Google结果,但他们都没有处理我想要做的事情(组合键和子类以及它们自己的主键)。

mappedBy 属性是强制性的。当关联是一对多关系时, mappedBy 属性放置在单侧(即在 User ' userdata 字段)。

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

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


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):

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.
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. It does however use the table which I specified for the Userdata class.

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.

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).

解决方案

The mappedBy attribute is mandatory at one of the sides of every bidirectional association. When the association is a one-to-many, the mappedBy attribute is placed ot the one- side (i.e. on the User's userdata field in your case).

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 (i.e. which join column or join table to use).

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. This will be much easier to handle, in all the layers of your application.

这篇关于JPA复合键@OneToMany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆