我正在尝试使用Spring JPA存储库创建查询。我有一个项目,其中包含允许访问该项目的组列表。给定属于一个或多个组的用户,我想查询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
答案 0 :(得分: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);
}