Search code examples
javahibernatejpaentitycriteria

Sorting with Criteria Builder by embedded attribute


I'm trying to fetch all entities of Foo sorted by time attribute of Embedded Bar. I have defined entities Foo that has embedded entity Bar as follows:

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

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

I have also static metamodels to use in my repository for both Foo an 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_;
}

Then in my repository I'm building a query with criteria builder:

@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));
    }
    ...
}

Execution of above code results in NullPointerException with following stack trace:

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 points to this line:

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

i can't understand why in my code Foo_.bar_ attribute is null resulting in NPE, could you please point my mistake?


Solution

  • ok, i found the answer, there were actualy few mistakes i made:

    • attribute in static model should have the same name as entity attribyte so in both statit models i had to remove _ suffix
    • since i was embedding other class and using Lombok as constructor provider and Bar did not have required constructor therefore, embedded entity was not initialized on creation time, resulting in object of class Foo attribute Bar was null