-
Notifications
You must be signed in to change notification settings - Fork 877
[BUG] Collection .contains() not working anymore #3618
Description
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)