【问题标题】:JPQL order by one of ElementCollectionElementCollection 之一的 JPQL 订单
【发布时间】:2012-03-10 09:41:40
【问题描述】:

我有以下实体:

Article
| 
+- @Id long id
|
+- @ElementCollection Map<Language, Translation> translations

Translation
|
+- @Column String name

我想要实现的是获取文章列表,按给定语言的名称排序。

类似:

SELECT a FROM Article a 
JOIN a.translations t WHERE t.language = ? 
ORDER BY t.name

问题是当使用t.language 时会抛出“无法解析属性”异常,即使language 列存在于 Translations 数据库表中。

我怎样才能实现这种行为?

【问题讨论】:

    标签: java hibernate jpa jpql


    【解决方案1】:

    我认为 Hibernate 不支持这一点。我只是将 Translation 设为实体而不是嵌入,并在 Translation 实体中包含一个语言字段。

    映射将是

     @OneToMany
     @JoinColumn(name = "article_id")
     @MapKey(name = "language")
     private Map<Language, Translation> translations;
    

    关联也可以是双向的,这样您的查询就会更加合乎逻辑且危险性更小,因为它可以返回翻译而不是文章:

    select t from Translation t 
    inner join fetch t.article 
    where t.language = :language 
    order by t.name
    

    【讨论】:

    • 谢谢!如果不更改实体的嵌入,是否有任何解决方案?它添加了数百万个我永远不会使用的值(用于翻译的 ID),而且我有点担心性能。
    • 它如何增加任何价值?数据库模式应该(或至少可以)是相同的。代理主键通常会提高性能,而不是降低性能。
    • 增加了ID栏。对于数百万行来说,这很重要。但我知道没有其他选择。
    • 您还有另一个选择:保持架构不变,并使用现有的 language-articleId 对作为翻译实体的复合 ID。
    • 规则在这里解释:docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/…。您需要一个 MapsId 注释来说明 ManyToOne Article 字段映射到与 articleId 字段相同的列。
    猜你喜欢
    • 2014-01-12
    • 2014-03-22
    • 1970-01-01
    • 2023-03-13
    • 2017-12-20
    • 1970-01-01
    • 2018-08-13
    • 2021-08-25
    • 2012-08-21
    相关资源
    最近更新 更多