querydsl: Collection .contains() not working anymore
Observed vs. expected behavior
The query that I wrote in the past previously was working with older Hibernate, now is not working.
Steps to reproduce
In the repository classes there are 3 methods and none of those is working:
[UserRepositoryImpl] findByUserRole_1()
org.hibernate.query.SemanticException: Operand of 'member of' operator must be a plural path
[UserRepositoryImpl] findByUserRole_2() Alternate where
clause also throws exception:
org.hibernate.query.QueryArgumentException:
Argument [ROLE_ADMIN] of type [com.thevegcat.app.config.UserRole]
did not match parameter type [java.util.Set (n/a)]
[UserRepository] findByUserRole_3() This one also used to work and now throws exception:
java.lang.ClassCastException:
class org.hibernate.metamodel.mapping.internal.BasicAttributeMapping cannot be cast to class
org.hibernate.sql.ast.tree.from.TableGroupJoinProducer
(org.hibernate.metamodel.mapping.internal.BasicAttributeMapping and
org.hibernate.sql.ast.tree.from.TableGroupJoinProducer are in unnamed module of loader 'app')
UserRole.java
public enum UserRole {
ROLE_ADMIN,
ROLE_ADVANCED,
ROLE_EDITOR,
ROLE_USER,
ROLE_ANONYMOUS
}
User.java
@Entity
public class User {
// ...
@Convert( converter = UserRolesConverter.class )
@Column( columnDefinition = "TEXT" )
private Set<UserRole> roles;
// ...
}
UserRepositoryImpl.java
public class UserRepositoryImpl
// ...
// case #1 - using user.roles.contains( userRole )
public List<User> findByUserRole_1( final UserRole userRole ) {
final QUser user = QUser.user;
return
new JPAQueryFactory( this.entityManager )
.selectFrom( user )
.where(
new BooleanBuilder().and( user.roles.contains( userRole ) ).getValue()
)
.fetch();
}
// case #2 - using user.roles.any().eq( userRole )
public List<User> findByUserRole_2( final UserRole userRole ) {
final QUser user = QUser.user;
return
new JPAQueryFactory( this.entityManager )
.selectFrom( user )
.where(
new BooleanBuilder().and( user.roles.any().eq( userRole ) ).getValue()
)
.fetch();
}
// ...
}
UserRepository.java
public interface UserRepository extends
PagingAndSortingRepository<User, Integer>,
CrudRepository<User, Integer>
{
// ...
@Query( "SELECT u FROM User u LEFT JOIN FETCH u.roles r WHERE :role IN ( r )" )
List<User> findByUserRole_3( UserRole role );
// ...
}
UserRolesConverter.java
public class UserRolesConverter implements AttributeConverter<Set<UserRole>, String>, Serializable {
@Serial private static final long serialVersionUID = -6105356555706277280L;
public static final TypeReference<Set<UserRole>> TYPE_REFERENCE = new TypeReference<>() { /**/ };
@Override
public String convertToDatabaseColumn( final Set<UserRole> attribute ) {
if( attribute == null || attribute.isEmpty() ) {
return null;
}
try {
return new ObjectMapper().writeValueAsString( attribute );
}
catch( final JsonProcessingException e ) {
return null;
}
}
@Override
public Set<UserRole> convertToEntityAttribute( final String dbData ) {
if( dbData == null ) {
return Collections.emptySet();
}
try {
final Set<UserRole> result = new ObjectMapper().readValue( dbData, TYPE_REFERENCE );
if( result == null ) {
throw new IllegalStateException( "This should never happen" );
}
return result;
}
catch( final JsonProcessingException e ) {
throw new IllegalStateException( "JsonProcessingException: " + e.getMessage() );
}
}
}
Environment
OS: Windows 11 Pro 23H2 22631.2506 Windows Feature Experience Pack 1000.22677.1000.0 IDE: Eclipse STS Version: 4.20.1.RELEASE Build Id: 202310260003 Revision: b4f357cb0399519f520df4fc968315d5735367da Spring: Spring Boot 3.1.5 Hibernate: Hibernate ORM 6.3.1.Final Querydsl version: 5.0.0 Querydsl module: querydsl-apt, querydsl-jpa, com.querydsl.apt.jpa.JPAAnnotationProcessor Database: mysql Ver 8.0.16 for Win64 on x86_64 (MySQL Community Server - GPL) JDK: openjdk version “17.0.7” 2023-04-18 OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7) OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode, sharing)
See also
https://stackoverflow.com/questions/77409442/querydsl-collection-contains
About this issue
- Original URL
- State: open
- Created 8 months ago
- Comments: 27 (8 by maintainers)
I cloned the repository and had a look at the errors. It doesn’t seem straightforward to fix. I will try to reproduce the errors in the querydsl repository as some unit tests and fix it there. Hibernate 6 changed the way the types of the query parameters get validated, I believe this is what is causing the issues now.
@H-Lo New release out with plenty of fixes on
java.time
territory, give it a shothttps://github.com/OpenFeign/querydsl/releases/tag/6.0.0.M2
@H-Lo doubt you will get any help here.
I tried to volunteer… but what the present team is looking for is NOT someone to keep the project active https://querydsl.slack.com/archives/C06KLG1BP/p1698220668765159
Since there is a conscientious choice to get this project on a death spiral, I forked it and start my own release cycles
https://github.com/OpenFeign/querydsl
There are 3 releases out already, latest one with first contributions from opensource.
5.1.1
at the very least contain fair less extremely old dependencies and was tested with java 21.@danielvion and myself are preparing for a major push towards querydsl 6.0 with hibernate 6 support.
At this stage, we are looking for volunteer to try it out.