HHH-17100 Fix CustomType to not call UserType#disassemble wrongly

This commit is contained in:
Christian Beikov 2023-09-04 18:22:08 +02:00
parent 9500820c2d
commit 1233372b2f
3 changed files with 34 additions and 8 deletions

View File

@ -190,22 +190,36 @@ public class CustomType<J>
@Override
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner) {
return (Serializable) disassemble( value, session );
return disassembleForCache( value );
}
@Override
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException {
return (Serializable) disassemble( value, (SharedSessionContractImplementor) null );
return disassembleForCache( value );
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
private Serializable disassembleForCache(Object value) {
final Serializable disassembled = getUserType().disassemble( (J) value );
// Since UserType#disassemble is an optional operation,
// we have to handle the fact that it could produce a null value,
// in which case we will try to use a converter for disassembling,
// or if that doesn't exist, simply use the domain value as is
if ( disassembled == null && value != null ) {
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) {
return disassembled;
}
else {
return (Serializable) valueConverter.toRelationalValue( (J) value );
}
}
return disassembled;
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
// Use the value converter if available for conversion to the jdbc representation
if ( value != null ) {
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) {
return value;
@ -214,7 +228,7 @@ public class CustomType<J>
return valueConverter.toRelationalValue( (J) value );
}
}
return disassembled;
return value;
}
@Override

View File

@ -40,7 +40,19 @@ public class ContributedUserTypeTest {
Assertions.assertTrue( type instanceof CustomType, "Type was initialized too early i.e. before type-contributors were run" );
}
@Entity
@Test
@JiraKey( "HHH-17100" )
public void testParameter(SessionFactoryScope scope) {
scope.inSession(
session -> {
session.createSelectionQuery( "from StringWrapperTestEntity e where e.stringWrapper = :p" )
.setParameter( "p", new StringWrapper( "abc" ) )
.getResultList();
}
);
}
@Entity(name = "StringWrapperTestEntity")
public static class StringWrapperTestEntity implements Serializable {
@Id
private Integer id;

View File

@ -96,13 +96,13 @@ public class StringWrapperUserType implements UserType<StringWrapper> {
@Override
public Serializable disassemble(StringWrapper value)
throws HibernateException {
return deepCopy( value );
return value == null ? null : value.getValue().getBytes();
}
@Override
public StringWrapper assemble(Serializable cached, Object owner)
throws HibernateException {
return deepCopy( (StringWrapper) cached );
return new StringWrapper( new String( (byte[]) cached ) );
}
@Override