【问题标题】:How to use @OneToOne with a @Where in Hibernate?如何在 Hibernate 中使用 @OneToOne 和 @Where?
【发布时间】:2018-06-27 09:44:23
【问题描述】:

我现在有 2 个实体,一个是 POST,另一个是 POST_DETAILPOST_DETAIL 存储POST 的不同翻译。

(简化)POST 架构:

- ID NUMBER

(简化)POST_DETAIL 架构:

 - ID NUMBER
 - REF_ID NUMBER  # FK to POST.ID
 - LANG VARCHAR
 - TITLE VARCHAR

我希望POST 中使用 Hibernate 注释(比如英语)POST_DETAIL 之一

class Post {
    ...
    // annotations
    private PostDetail postDetailEn;
}

感谢任何帮助

编辑: 我希望做类似的事情

class Post {
    ...
    @OneToOne(mappedBy = "post")
    @JoinColumn(name = "ID", referencedColumnName = "REF_ID", 
                insertable = false, updatable = false)
    @Where(clause = "POST_DETAIL.LANG = 'EN'")           // not working
    @WhereJoinTable(clause = "POST_DETAIL.LANG = 'EN'")  // not working
    private PostDetail postDetailEn;
}

class PostDetail {
    ...

    @OneToOne
    @JoinColumn(name = "REF_ID", insertable = false, updatable = false)
    @Where(clause = "LANG = 'EN'")           // not working
    @WhereJoinTable(clause = "LANG = 'EN'")  // not working
    private Post post;

    @Column(name = "REF_ID")
    private Long refId;        

    @Column(name = "LANG")
    private String lang;
}

但是hibernate记录的sql没有显示where子句

编辑:例如: 数据库中的记录

+-----------+  +-----------------+  +-----------------+
| Post (#1) |  | PostDetail (#1) |  | PostDetail (#2) |
+-----------+  |    refId: 1     |  |    refId: 1     |
               |    lang : EN    |  |    lang : EN    |
               +-----------------+  +-----------------+

我想得到

Post(id=1, 
     postDetail=PostDetail(id=1, 
                           refId=1, 
                           lang=EN))

【问题讨论】:

    标签: java hibernate one-to-one


    【解决方案1】:

    我发现这篇关于@JoinFormula的帖子,我也有类似的情况。

    由于我只需要在Post 中添加一个PostDetail,因此我没有在PostDetail 中添加Post 字段,我的工作解决方案是

    class Post {
        ...
        @ManyToOne(fetchType = FetchType.LAZY)
        @JoinFormula("(SELECT D.ID FROM POST_DETAIL D WHERE D.REF_ID = ID AND D.LANG = 'EN')")
        private PostDetail postDetailEn;
    }
    

    【讨论】:

      【解决方案2】:
      class Post {
          @OneToOne
          @JoinColumn(name = "ID", referencedColumnName = "REF_ID")
          private PostDetail postDetailEn;
      }
      

      【讨论】:

      • 但是一个 POST 会有多个 POST_DETAIL(针对不同的语言),如何指定 where 子句lang = 'EN'
      • 我检查了休眠日志并发现查询的 where 子句正在比较 PostDetailID 而不是 REF_ID
      • 如何在PostDetail类中声明REF_ID字段?
      • @Column(name = “REF_ID”) private Long refId;
      【解决方案3】:

      您应该为此使用@OneToOne 注释。

      业主方

       class Post {
             @OneToOne(cascade = CascadeType.ALL)
             @JoinColumn(name = "postdetail_id")
             private PostDetail postDetail;
          }
      

      【讨论】:

      • 我希望在 Post 中只有一个(例如 lang='EN')PostDetail 而不是它们的列表。我怎样才能做到这一点?感谢您的帮助
      • 那么你应该使用 OneToOne 和 JoinColumn 注释而不是 OneToMany。
      • 会有几个PostDetail 具有不同的lang 但相同的refIdPost。但我只想在Post 中有一个(lang='EN'PostDetail。我想我还需要指定一些where 子句?
      • 使用OneToOne,每个帖子可以有一个postdetail,postdetail只能与单个帖子关联,不会与任何其他帖子关联。如果您希望在其他人之间共享 postdetail,那么您可以使用 ManyToOne。
      • 检查@PrimaryKeyJoinColumn 注释。使用这个,Post 表的 PK 将是 PostDetail 表的 PK,也将是 Post 表的 FK。
      猜你喜欢
      • 2011-12-03
      • 2015-05-12
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2013-08-19
      • 2015-08-09
      • 2016-05-09
      • 1970-01-01
      相关资源
      最近更新 更多