使用嵌入式属性按Criteria Builder排序

时间:2019-01-03 13:20:50

标签: java hibernate jpa entity criteria

我正在尝试获取按嵌入栏的时间属性排序的Foo的所有实体。我已经定义了嵌入了实体Bar的实体Foo,如下所示:

public class Foo {
    ...
    @Embedded
    private Bar bar;
    ...
}

@Embeddable
public class Bar {
    ...
    @Column(name = "TIME")
    private Date time;
    ...
}

我在存储库中还为两个Foo a Bar使用了静态元模型:

@StaticMetamodel(Foo.class)
public class Foo_{
    ...
    public static volatile SingularAttribute<Foo, String> attribute_;
    public static volatile SingularAttribute<Foo, Bar> bar_;
    ...
}

@StaticMetamodel(Bar.class)
public class Bar_{
    public static volatile SingularAttribute<Bar, Date> time_;
}

然后在我的存储库中,使用条件构建器构建查询:

@Repository
public class FooRepositoryImpl implements FooRepository {
    ...
    @Override
    public Page<Foo> findAllWithPagingAndFilter(PageRequest pageRequest, String attribute) {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
        Root<Foo> root = criteriaQuery.from(Foo.class);
        Predicate attributePredicate= criteriaBuilder.equal(root.get(Foo.attribute_), attribute);
        criteriaQuery.where(attributePredicate);
        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Foo_.bar_).get(Bar_.time_)));
        TypedQuery<Comment> typedQuery = entityManager.createQuery(criteriaQuery);
        typedQuery.setFirstResult((pageRequest.getPageNumber()) * pageRequest.getPageSize());
        typedQuery.setMaxResults(pageRequest.getPageSize());
        return new PageImpl<>(typedQuery.getResultList(), pageRequest, genericCountWithPredicates(Foo.class, attributePredicate));
    }
    ...
}

执行上述代码会在NullPointerException中产生以下堆栈跟踪:

java.lang.NullPointerException: null
    at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:123)
    at com.project.server.repositories.impl.FooRepositoryImpl.findAllWithPagingAndFilter(FooRepositoryImpl.java:52)
    at com.project.server.repositories.impl.FooRepositoryImpl$$FastClassBySpringCGLIB$$7a99bbb7.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

FooRepositoryImpl.java:52指向此行:

criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Foo_.bar_).get(Bar_.time_)));

我无法理解为什么在我的代码中Foo_.bar_属性为null会导致NPE,请指出我的错误吗?

1 个答案:

答案 0 :(得分:0)

好的,我找到了答案,实际上我犯了一些错误:

  • 静态模型中的属性应与实体attribyte名称相同,因此在两种状态模型中,我都必须删除_后缀
  • 由于我正在嵌入其他类,并使用Lombok作为构造函数提供程序,并且Bar不需要构造函数,因此,嵌入式实体未在创建时初始化,导致Foo属性Bar类的对象为空