[JIRA] (HHH-15743) Querying with empty parameter list fails
by Christian Beikov (JIRA)
Christian Beikov ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *commented* on HHH-15743 ( https://hibernate.atlassian.net/browse/HHH-15743?atlOrigin=eyJpIjoiOWMyMj... )
Re: Querying with empty parameter list fails ( https://hibernate.atlassian.net/browse/HHH-15743?atlOrigin=eyJpIjoiOWMyMj... )
>
>
>
> The widely used Spring Framework and its module Spring Data JPA encourage
> using queries the way I described
>
>
That’s new to me. Can you show me a reference where this is explicitly stated?
>
>
>
> This repository method generates a Hibernate query and makes providing departments
> mandatory (empty list returns 0 result, null returns
> IllegalArgumentException).
>
>
Because this implies that nobody encourages this kind of usage.
>
>
>
> Spring 5 (with Hibernate 5) made it easy to provide optional departments :
>
>
>
I’m sorry you based part of your application on something unspecified which just happened to work in this particular case, but like I wrote before, this kind of query is very inefficient. Don’t use that. Go the extra mile and implement proper conditional filtering.
>
>
>
> With Spring 6 (including Hibernate 6) I have to implement it via Criteria
> API and Custom Repositories (
> https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repos...
> ) , which is more costlier and verbose
>
>
You don’t. I’d suggest everyone to use Spring Data Specification here for this purpose.
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("from User u " +
"where COALESCE(:departments) is null or u.department in (:departments)")
default List<User> findAllByOptionalDepartmentIn(
@Param("departments") List<Department> departments,
Sort sort) {
return findAllByOptionalDepartmentIn( (root, query, cb) -> {
return departments.isEmpty()
? null
: root.get("department").in(departments)
}, sort );
}
List<User> findAllByOptionalDepartmentIn(
Specification<User> spec,
Sort sort);
}
( https://hibernate.atlassian.net/browse/HHH-15743#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-15743#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100210- sha1:eab5823 )
2Â years, 10Â months
[JIRA] (HHH-15743) Querying with empty parameter list fails
by Robert Rittwag (JIRA)
Robert Rittwag ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *commented* on HHH-15743 ( https://hibernate.atlassian.net/browse/HHH-15743?atlOrigin=eyJpIjoiYjg0Mz... )
Re: Querying with empty parameter list fails ( https://hibernate.atlassian.net/browse/HHH-15743?atlOrigin=eyJpIjoiYjg0Mz... )
I get your point. And I respect it.
In my former comment I forgot a third and quite important aspect:
The widely used Spring Framework and its module Spring Data JPA encourage using queries the way I described. Because of their mechanism of generated repositories ( https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repos... ) it is quite easy to implement a query this way:
@Repository
public interface UserRepository extends JpaRepository<User, Long > {
List<User> findAllByDepartmentIn(
@Param( "deparment" ) List<Department> departments,
Sort sort);
}
This repository method generates a Hibernate query and makes providing departments mandatory (empty list returns 0 result, null returns IllegalArgumentException). Spring 5 (with Hibernate 5) made it easy to provide optional departments :
@Repository
public interface UserRepository extends JpaRepository<User, Long > {
@Query( "from User u " +
"where COALESCE(:departments) is null or u.department in (:departments)" )
List<User> findAllByOptionalDepartmentIn(
@Param( "departments" ) List<Department> departments,
Sort sort);
}
With Spring 6 (including Hibernate 6) I have to implement it via Criteria API and Custom Repositories ( https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repos... ) , which is more costlier and verbose:
interface CustomizedUserRepository {
List<User> findAllByOptionalDepartmentIn(List<Department> departments, Sort sort);
}
public class CustomizedUserRepositoryImpl implements CustomizedUserRepository {
@Autowired
private EntityManager em;
@Override
public List<User> findAllByOptionalDepartmentIn(
@Param( "departments" ) List<Department> departments,
Sort sort) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cr = cb.createQuery(User.class);
Root<User> root = cr.from(User.class);
if (departments != null && !departments.isEmpty())
cr.select(root).where(root.get( "department" ).in(departments));
// TODO: add some sort magic
return em.createQuery(cr).getResultList();
}
}
@Repository
public interface UserRepository extends JpaRepository<User, Long >, CustomizedUserRepository {
}
My point is: The newly released Spring 6 leaves a lot of Spring 5 users asking why and how to migrate their simple queries. That's why I created this issue … and was talking about shady "workaround solutions" 🙂 .
( https://hibernate.atlassian.net/browse/HHH-15743#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-15743#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100210- sha1:eab5823 )
2Â years, 10Â months