我在Hibernate6(迁移到Spring Boot3)上遇到了一个问题.我有一个主实体类BaseEntity
,它的status
属性是类CustomStatus
.在Hibernate/JPA查询中,我喜欢使用这种语法select * from BaseEntity where status = 'ARCHIVED'
或select * from BaseEntity where status NOT IN ('ARCHIVED', 'CANCELLED')
.这可以很好地处理原生查询,但我喜欢使用JPA来调用服务.
编译是可以的,但在运行时,我在查询执行时收到一个错误:
Can't compare test expression of type [BasicSqmPathSource(status : CustomStatus)] with element of type [basicType@4(java.lang.String,12)]
.
最初(Hibernate5/Spring Boot2.7),引用AbstractSingleColumnStandardBasicType
/AbstractTypeDescriptor
的@Type
做得很好.
BaseEntity个
@Table(name="base_entity")
public class BaseEntity {
@Id
private Integer id;
@JavaType(CustomStatusJavaType.class)
@JdbcTypeCode(SqlTypes.VARCHAR)
private CustomStatus status;
}
CustomStatus个个
public class CustomStatus implements Serializable {
private final String name;
public CustomStatus (final String name) { this.name = name;}
}
CustomStatusJavaType个
public class CustomStatusJavaType extends AbstractClassJavaType<CustomStatus> {
public static final CustomStatusJavaType INSTANCE = new CustomStatusJavaType ();
public CustomStatusJavaType () {
super(CustomStatus.class);
}
@Override
public String toString(CustomStatus value) {
if (value == null) return null;
return value.getName();
}
@Override
public CustomStatus fromString(CharSequence str) {
if (str == null || str.length() == 0) return null;
return new CustomStatus(str.toString());
}
@Override
public <X> X unwrap(CustomStatus value, Class<X> type, WrapperOptions options) {
if (value == null) return null;
return StringJavaType.INSTANCE.unwrap(
value == null ? null : value.getName(),
type,
options
);
}
@Override
public <X> CustomStatus wrap(X value, WrapperOptions options) {
if (value == null) return null;
return new CustomStatus (StringJavaType.INSTANCE.wrap( value, options));
}
}
UPDATE with AttributeConverter
CustomStatus个个
@Converter
public class CustomStatusAttributeConverter implements AttributeConverter<CustomStatus, String> {
@Override
public String convertToDatabaseColumn(CustomStatus status) {
return (null == status? null : status.getName());
}
@Override
public CustomStatus convertToEntityAttribute(String s) {
return (s == null || s.isEmpty() ? null : new CustomStatus(s));
}
}
public class BaseEntity {
@Id
private Integer id;
@Convert(converter = CustomStatusAttributeConverter.class)
private CustomStatus status;
}
遗憾的是,我得到了同样的错误……如果我编写原生查询,但不使用JPA查询,它就会起作用.