Criteria API JPA Hibernate:外键上的不同选择

Posted

技术标签:

【中文标题】Criteria API JPA Hibernate:外键上的不同选择【英文标题】:Criteria API JPA Hibernate: Distinct select on foreign key 【发布时间】: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 子句中。

【问题讨论】:

【参考方案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 对象按stringValueItemEntry 排序,我正在尝试为此找到解决方案。无论如何,如果您有任何想法,如果您能与我分享这个想法,我将不胜感激。 那么,如果item1有“a”、“b”,item2有“b”和“c”,item3有“a”、“a”和“c”,那么应该是什么订购?

以上是关于Criteria API JPA Hibernate:外键上的不同选择的主要内容,如果未能解决你的问题,请参考以下文章

JPA & Criteria API - 仅选择特定列

jpa criteria-api:加入子选择

JPA/Criteria API - Like & equal 问题

Jersey API + JPA/Hibernate Criteria延迟加载不起作用

JPA Criteria Query API 和两列排序

Criteria API JPA Hibernate:外键上的不同选择