【问题标题】:Spring JPA Query Check If At Least One Element of a List Exists in Parameter ListSpring JPA查询检查参数列表中是否存在至少一个列表元素
【发布时间】:2016-07-06 20:36:37
【问题描述】:

我正在尝试使用 Spring JPA 存储库创建查询。我有一个项目,其中包含允许访问该项目的组列表。给定一个属于一个或多个组的用户,我想查询 Item 表并返回该用户属于至少一个 Item 允许的组的所有 Item。

@Query("select item from Item item where item.allowedGroups.id in ?1")
Page<Object> findByAllowedGroups(List<Long> userGroupIds, Pageable pageable);

然而,这会导致以下异常:

org.hibernate.QueryException: illegal attempt to dereference collection [item0_.id.allowedGroups] with element property reference [id]

理想情况下,我会在 item.allowedGroups 和 userGroupIds 参数上执行 JOIN,但我无法确定如何对 JPA 查询的参数执行 JOIN。

基本上,我需要知道推荐的 Spring JPA 查询解决方案是什么,用于确定给定参数中是否存在对象列表字段的至少一个元素。

物品类别:

@Entity
@Table(name = "item")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Item extends AbstractAuditingEntity implements Serializable,Comparable<File> {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@ManyToMany(fetch = FetchType.EAGER)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "item_allowed_groups",
    joinColumns = @JoinColumn(name="item_id"),
    inverseJoinColumns = @JoinColumn(name="group_id"))
private Set<Group> allowedGroups = Sets.newHashSet();

// getters and setters

组类:

@Entity
@Table(name = "group")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Group implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@NotNull
@Size(max = 50)
@Column(name = "name", length = 50, nullable = false)
private String name;

// getters and setters

【问题讨论】:

  • 能否提供JPA实体代码?
  • 文档中解释了联接:docs.jboss.org/hibernate/orm/5.1/userguide/html_single/…。用对象替换人,用组替换电话,你就有了你需要的查询。调用您的实体Object 是一个糟糕的主意。不要那样做。
  • 我认为文档中的任何示例都不能解决我的困境。问题是我想对作为参数传递的组 ID 列表进行 JOIN,而不仅仅是表中已经存在的组。

标签: java spring-data-jpa jpql


【解决方案1】:

我通过设置 Spring JPA QueryDSL 并在此 Stack Overflow 答案中实施解决方案解决了这个问题:https://stackoverflow.com/a/33455117/3285398。我将 BooleanExpression 修改为以下内容:

public static BooleanExpression hasItemAccess(List<Group> groups) {
    QItem item = QItem.item;
    return item.allowedGroups.any().in(groups);
}

并在ItemRepository中添加了一个查询方法:

public interface ItemRepository extends JpaRepository<Item,Long>, QueryDslPredicateExecutor<Item> {

@Query("select item from Item item where item.user.login = ?#{principal.username}")
Page<Item> findByUserIsCurrentUser(Pageable pageable);

Page<Item> findAll(Predicate predicate, Pageable pageable);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2020-05-11
    • 2017-03-14
    • 2022-01-06
    • 2015-07-23
    • 2021-12-17
    相关资源
    最近更新 更多