【问题标题】:EclipseLink - Query failed to prepare, unexpected error occurredEclipseLink - 查询准备失败,发生意外错误
【发布时间】:2018-03-26 16:31:36
【问题描述】:

执行命令时,EntityManager 抛出(all https://pastebin.com/zKYBhsv8)

[EL Warning]: 2017-10-14 20:07:55.332--UnitOfWork(402037615)--Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.QueryException
Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.NullPointerException].
Internal Exception: java.lang.NullPointerException
Query: ReportQuery(referenceClass=MovieEntity )

代码如下所示

我创造

final CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
final Root<MovieEntity> root = countQuery.from(MovieEntity.class);

然后我创建谓词

final Predicate whereClause = MovieSpecs
            .getFindPredicate(root, cb, countries);

这是方法

public static Predicate getFindPredicate(
        final Root<MovieEntity> root,
        final CriteriaBuilder cb
        final List<CountryType> countries
) {
    final List<Predicate> predicates = new ArrayList<>();
    if(countries != null && !countries.isEmpty()) {
        final List<Predicate> orPredicates =
                countries
                        .stream()
                        .map(status -> cb.equal(root.get(MovieEntity_.countries), countries))
                        .collect(Collectors.toList());
        predicates.add(cb.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
    }
    return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}

然后在countQuery中设置谓词

countQuery.select(cb.count(root)).where(whereClause);

并执行命令

final Long count = this.entityManager.createQuery(countQuery).getSingleResult();

我在这里抛出上述错误。

MovieEntity:https://pastebin.com/CvhEQFZDMovieEntity_:http s://pastebin.com/ZyJL0nmM

【问题讨论】:

  • 你能详细说明你想和这个cb.equal(root.get(MovieEntity_.countries), countries)比较吗?
  • 现在我认为并看到它毫无意义。使用此代码,我想检查给定国家是否在电影国家列表中。你知道怎么做吗?
  • 使用 'in' 检查一个元素是否在列表中,但您需要更具体一些,因为在列表中的两个国家/地区播放的电影将在您的结果中显示两次,原因是通过 OneToMany 关系加入。

标签: java spring jpa spring-boot eclipselink


【解决方案1】:

假设您希望所有MovieEntities 都具有一个或多个提供的Countries,您可以尝试将cb.equal(root.get(MovieEntity_.countries), countries) 替换为cb.isMember(status, MovieEntity_.countries)

但是,这可能不是执行此操作的最佳方式,但至少最容易针对您当前的代码进行测试。也许您还应该将status 更改为country 以使代码更易于理解。

【讨论】:

    【解决方案2】:

    我认为当 EclipseLink 尝试处理针对集合完成的 countries 匹配时会出现问题:

    .map(status -> cb.equal(root.get(MovieEntity_.countries), *countries*))
    

    我认为您的意图是检查与流式传输的项目是否相等

    .map(status -> cb.equal(root.get(MovieEntity_.countries), status))
    

    【讨论】:

    • 不幸的是,这没有帮助。你可以看看它 service pastebin.com/4tY5djAD 和 getFindPredicate pastebin.com/4eQb6yUE
    • 您能否将MovieEntity 的ORM 映射添加到问题中?
    • 我正在编辑。最好的事情是错误仅在列表中。单个对象没有问题。
    • 这可能听起来很神奇,但请尝试下一个:而不是构建标准,将集合与对象进行比较,将 MovieEntity.countries.idcountry.id 进行比较。当关系外键位于集合项上时,我之前已经看到此类查询的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多