Hello!
I recently migrated a project to SpringBoot 3.0.3 / Hibernate 6.1.7
The model has java.time.YearMonth
attributes being mapped to integers on the DB (MariaDB)
Here is how it was used:
@Convert(converter = YearMonthConverter.class)
@Column(name = "month", nullable = false)
private YearMonth month;
And here is the converter class (based on Jakarta now):
public class YearMonthConverter implements AttributeConverter<YearMonth, Integer> {
@Override
public Integer convertToDatabaseColumn(YearMonth attribute) {
return attribute == null ? null : (attribute.getYear() * 100) + attribute.getMonth().getValue();
}
@Override
public YearMonth convertToEntityAttribute(Integer dbData) {
return dbData == null ? null : YearMonth.of(dbData / 100, dbData % 100);
}
}
I’ve got a MAX() query on this column which fails with the following error:
org.hibernate.QueryException: Parameter 1 of function max() has type COMPARABLE, but argument is of type java.time.YearMonth
I’ve tried multiple things, debugging in the hibernate core classes to find ideas / solutions:
- Defining a
YearMonthJavaType extends AbstractClassJavaType<YearMonth>
based on the other time-related classes defined in Hibernate core, and registering it with@JavaTypeRegistration(javaType = YearMonth.class, descriptorClass = YearMonthJavaType.class)
- Creating a
YearMonthUserType implements UserType<YearMonth>
applied on my attribute with@Type(value = YearMonthUserType.class)
It’s worth noticing that the ORM is able to read/write this column from the DB, it only fails to run functions like MIN or MAX.
The debugging took me to a section of the code in ArgumentTypesValidator
where the code considers that the node type YearMonth
is a VarbinaryTypeDescriptor
and so incompatible with the FunctionParameterType
COMPARABLE
.
I’m running out of ideas, so any help would be appreciated
Thanks,
Guillaume