首页 > 解决方案 > 按实体搜索,其中列表包含 Java Hibernate 中传递的列表中的至少一个值

问题描述

假设我有一个实体:

@Getter
@Setter
@Entity
@Table(name = "rg_request")
@TypeDef(name = "listTypeConverter", typeClass = ListTypeConverter.class)
public class Request {

    @Id
    @GeneratedValue
    @Column(name = "request_id", updatable = false)
    private Long id;

    @Column(name = "shop_group_ids")
    @Type(type = "listTypeConverter")
    private List<UUID> shopGroupIds;

    @Column(name = "brand_id", columnDefinition = "uuid", updatable = false)
    @Type(type = "pg-uuid")
    private UUID brandId;
}

我想在数据库中使用 queryDsl 查找那些包含在 shopGroupIds 字段中的请求至少与传递的 shopGroup 匹配

public Page<Request> getRequests(Integer page, List<String> criteria,
                                 List<String> sort, Integer pageSize) {
        return requestRepository.findAll(
                getPredicate(criteria),
                PageRequest.of(page, pageSize, SortUtils.parseSortList(sort, request.orderColumn, DESC))
        );
}

private Predicate getPredicate(List<String> criteria) {
        List<UUID> shopGroupIds = shopGroupService.getShopGroupsByOwner(getCurrentUserId()).stream()
                .map(ShopGroup::getId)
                .collect(toList());
        return SearchCriteriaBuilder.builder()
                .forEntity(Request.class)
                .filters(criteria)
                .build()
                .and(request.shopGroupIds.any().in(shopGroupIds));
}

在该类的Page <T> findAll(Predicate predicate, Pageable pageable)方法中QuerydslJpaPredicateExecutor,当您调用 q 时uerydsl.applyPagination (pageable, createQuery (predicate) .select (path)),会形成以下查询:

  select request
from Request request
where ?1 = ?1 and request.brandId = ?2 and exists (select 1
from Request request_105380127
  inner join request_105380127.shopGroupIds as request_shopGroupIds_0
where request_105380127 = request and request_shopGroupIds_0 in (?3))
order by request.id asc

query.fetch()被调用时,我得到 NullPointerException

没有这个片段:.and(request.shopGroupIds.any().in(shopGroupIds))所有作品

有谁知道问题可能是什么?

列表类型转换器:

public class ListTypeConverter {

    @Override
    public int[] sqlTypes() {
        return new int[] { Types.ARRAY };
    }

    @Override
    public Class<?> returnedClass() {
        return List.class;
    }

    @Override
    public List<?> nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
        Array array = rs.getArray(names[0]);
        return array == null ? null : Arrays.asList((Object[]) array.getArray());
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
        Connection c = st.getConnection();
        if (value == null) {
            st.setNull(index, Types.ARRAY);
        } else {
            st.setArray(index, c.createArrayOf("text", ((List<?>) value).toArray()));
        }
    }
}

标签: javahibernateentityquerydsl

解决方案


推荐阅读