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 @Override
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner) { public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner) {
return (Serializable) disassemble( value, session ); return disassembleForCache( value );
} }
@Override @Override
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException { public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException {
return (Serializable) disassemble( value, (SharedSessionContractImplementor) null ); return disassembleForCache( value );
} }
@Override private Serializable disassembleForCache(Object value) {
public Object disassemble(Object value, SharedSessionContractImplementor session) {
final Serializable disassembled = getUserType().disassemble( (J) value ); final Serializable disassembled = getUserType().disassemble( (J) value );
// Since UserType#disassemble is an optional operation, // Since UserType#disassemble is an optional operation,
// we have to handle the fact that it could produce a null value, // 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, // 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 // or if that doesn't exist, simply use the domain value as is
if ( disassembled == null && value != null ) { 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(); final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) { if ( valueConverter == null ) {
return value; return value;
@ -214,7 +228,7 @@ public class CustomType<J>
return valueConverter.toRelationalValue( (J) value ); return valueConverter.toRelationalValue( (J) value );
} }
} }
return disassembled; return value;
} }
@Override @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" ); 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 { public static class StringWrapperTestEntity implements Serializable {
@Id @Id
private Integer id; private Integer id;

View File

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