【问题标题】:Secondarytables or OnetoOne associations?Secondarytables 还是 OnetoOne 关联?
【发布时间】:2011-03-31 13:48:05
【问题描述】:

考虑以下“模型”:

USER
    Long: PK
    String: firstName
    String: lastName

USER_EXT
    Long: PK
    String: moreInfo
    Date: lastModified

我正在尝试查找/创建正确的 Hibernate 映射(使用注释),这样,使用像“来自用户”这样简单的 HQL 查询,它将生成以下 SQL:

select firstName, moreInfo from USER, USER_EXT where user.pk = user_ext.pk

我已经尝试了所有方法,从使用 @Secondarytable 到 @OneToOne 关联,但我无法让它工作。

我现在得到的最好结果是使用@OneToOne 关联生成多个 SQL 查询,其中一个用于获取 USER 中的行,而对于结果集中的每一行,一个来自 USER_EXT 的选择查询。

这是非常无效的。

有什么想法吗?

【问题讨论】:

    标签: hibernate hql one-to-one


    【解决方案1】:

    OneToOneSecondarytable 之间进行选择取决于对象模型(即,如果您想要用户扩展的实体)。我选择使用OneToOne 关联和两个实体。

    对于User(注意使用PrimaryKeyJoinColumn作为共享主键):

    @Entity
    public class User {
    
        @Id private Long id;
        private String firstName;
        private String lastName;
    
        @OneToOne
        @PrimaryKeyJoinColumn
        private UserExt userExt;
    
        public UserExt getUserExt() {
            return userExt;
        }
        public void setUserExt(UserExt userExt) {
            this.userExt = userExt;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getFirstName() {
            return firstName;
        }
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
        public String getLastName() {
            return lastName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    }
    

    还有UserExt

    @Entity
    public class UserExt {
    
        @Id private Long id;
        private String moreInfo;
        @Temporal(TemporalType.DATE)
        private Date lastModified;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getMoreInfo() {
            return moreInfo;
        }
        public void setMoreInfo(String moreInfo) {
            this.moreInfo = moreInfo;
        }
        public Date getLastModified() {
            return lastModified;
        }
        public void setLastModified(Date lastModified) {
            this.lastModified = lastModified;
        }   
    }
    

    使用上述实体,以下 HQL 查询:

    select u.firstName, u.userExt.moreInfo from User u
    

    生成以下 SQL 查询:

    select
      userx0_.firstName as col_0_0_,
      userextx1_.moreInfo as col_1_0_ 
     from
      User userx0_,
      UserExt userextx1_ 
     where
      userx0_.id=userextx1_.id
    

    这是预期的结果。

    PS:JPA 1.0 实际上对派生标识符的支持很差(JPA 2.0 中的情况要好得多),您必须在 UserExt 上手动设置 Id,除非您使用 Hibernate 特定的 foreign 生成器.有关详细信息,请参阅下面的问题。

    相关问题

    【讨论】:

    • 感谢您的回答。实际上,我目前正在使用 @SecondaryTable 和只有一个实体进行测试。到目前为止,一切似乎都有效,除了以下内容:我的用户实体中有一个与“UserExt”表相关的@ManyToMany 关联。我不能使外键约束来引用 USER_EXT 表。使用:@SecondaryTable(name = "USER_EXT") public class User { 。 ... @ManyToMany @JoinTable(name = "USEREXT_ACCOUNT", joinColumns = { @JoinColumn(table="USER_EXT", name = "USER_ID") }) ... }
    • 我得到的是 DDL:alter table USEREXT_ACCOUNT 添加约束 FK65656DF 外键 (USER_ID) 引用 USER 而不是 'references USER_EXT'
    • @David:我想知道在SecondaryTable 上加入ManyToMany 是否有意义,因为ManyToMany 应该指向一个实体(因此使用“主要”的PK连接表)。我认为不会。也许在这里提供您的对象模型会有所帮助。但恕我直言,这是一个完全不同的问题。您应该打开一个问题。
    • 只要我的 HQL 看起来像您的 HQL(从用户 u 中选择 u.firstName、u.userExt.moreInfo)并请求特定属性,就按照您建议的方式进行操作。当请求完整的实体时,它会生成太多的 SQL。我会修改我的问题。
    • @David:感谢您完全改变了您的问题(标题和正文),使我的回答几乎无关紧要。请回滚更改并打开一个新问题(正如我已经暗示的那样),我不会在这里回答。
    猜你喜欢
    • 1970-01-01
    • 2011-06-05
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多