【问题标题】:Criteria API JPA Hibernate: Distinct select on foreign keyCriteria API JPA Hibernate:外键上的不同选择
【发布时间】:2016-07-08 10:24:43
【问题描述】:

给出以下实体结构:

@Entity
public class Item {
    @Id @GeneratedValue
    private Long id;
    @OneToMany
    private Set<ItemEntry> itemEntries;

    public Item() {
        itemEntries = new HashSet<>();
    }

    // Getters and setters
}

@Entity
public class ItemEntry {
    @Id @GeneratedValue
    private Long id;
    private String stringValue;
    @ManyToOne
    private Item item;

    public Item() {}

    // Getters and setters
}

这将解析为数据库表 ItemEntry,如下所示:

| id | stringValue | item_id |

我需要在 JPA 环境(持久性提供程序是 Hibernate)和规范元模型中使用 Criteria API 查询此数据库表。

查询是检索所有 distinct Item 对象,其中 stringValue 类似于 %my%。请注意,与 %my% 匹配的 stringValue 可能会多次分配给 Item。

到目前为止,我有以下代码:

final CriteriaQuery<ItemEntry> itemEntryQuery = criteriaBuilder.createQuery(ItemEntry.class);
final Root<ItemEntry> itemEntryRoot = criteriaQuery.from(ItemEntry.class);
final Path<Item> selection = itemEntryRoot.get(ItemEntry_.item);
itemEntryQuery.select(selection).where(...).distinct(true);

编译器发出错误声明

The method select(Selection&lt;? extends ItemEntry&gt;) in the type CriteriaQuery&lt;ItemEntry&gt; is not applicable for the arguments (Path&lt;Item&gt;)

是否有另一种可能性来实现我正在寻找的东西?此时,我不能使用SetJoin&lt;Item, ItemEntry&gt;,因为我需要按stringValue 对结果进行排序,这是不可能的,因为按项目排序需要出现在不同查询的选择列表中。如果我使用SetJoin&lt;Item, ItemEntry&gt;,则只有Item 的字段出现在select 子句中。

【问题讨论】:

    标签: hibernate criteria-api jpa-2.1


    【解决方案1】:

    在CriteriaQuery&lt;T&gt;中,T是查询结果的类型。您希望查询返回 Items,而不是 ItemEntries,因此它应该是 CriteriaQuery&lt;Item&gt;。

    请注意,对于不基于多个条件且不需要动态构建的查询,我真的会避免条件查询。一个简单的 JPQL 更加简单易读:

    select distinct item from ItemEntry entry 
    join entry.item item
    where entry.stringValue like :param
    

    【讨论】:

    • 感谢您的回答。 where 条件是动态构建的,因此使用 Criteria API 似乎是合法的。基本上,我同意我需要处理Item 对象。我需要它“反过来”工作的主要原因在我的问题中说明:“此时,我不能使用 SetJoin 因为我需要 按 stringValue 排序结果不可能,因为按项目排序需要出现在不同查询的选择列表中。".
    • 这就是为什么我认为最好在ItemEntry 类中对item_id 执行不同的查询并在另一个查询中获取Item 对象。
    • 这对我来说没有多大意义。您如何通过 Item 中不存在的字段对 Item 进行排序?但无论如何,这与你的问题没有太大关系。如果您想要一个返回 Item 的查询,您需要一个 CriteriaQuery,而不是 CriteriaQuery。
    • 简单来说,要求是让Item 对象按stringValue 的ItemEntry 排序,我正在尝试为此找到解决方案。无论如何,如果您有任何想法,如果您能与我分享这个想法,我将不胜感激。
    • 那么,如果item1有“a”、“b”,item2有“b”和“c”,item3有“a”、“a”和“c”,那么应该是什么订购?
    猜你喜欢
    • 2013-06-21
    • 1970-01-01
    • 2012-06-11
    • 2015-02-15
    • 2014-06-13
    • 2012-09-19
    • 2019-11-10
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多