Using a legacy db schema with newest Hibernate 6.3.1.Final with Spring Boot 3.1.4 has had quite a few code migration work needed for JPA models. Most of my issues currently are with Enum types. I've had issue with Enums in the mysql database that were stored as int(11) producing "expecting #TINYINT" errors, which I could only solve by changing the column type in the db (something that would break legacy code). I tried these changes to the annotation to no avail, and I couldn't find any other solution in blogs. Note: I did not have these validation issues with Hibernate 6.0.1.Final:
@Column(name="status", columnDefinition = "INTEGER") or @Column(name="status", columnDefinition = "int2")
Another issue was with "@Enumerated(EnumType.STRING)", which doesn't seem to work at all. Documentation from https://docs.jboss.org/hibernate/orm/6.3/introduction/html_single/Hibernate_Introduction.html#enums isn't complete or no longer accurate. I have an enum in a legacy database stored as "varchar(255)", with the following JPA definition:
@Column(name = "status", nullable = false)
@Enumerated(EnumType.STRING)
@Basic(optional=false)
private ActiveOrInactive status;
And I get the following error on validation:
found [varchar (Types#VARCHAR)], but expecting [enum ('active','inactive') (Types#ENUM)]
Again, I did not get this issue with Hibernate 6.0.1.Final.
What changes should I make to my annotation for Enums stored as int(11) or varchar(255) in Mysql db?
import java.util.HashMap;
import java.util.Map;
public enum ActiveOrInactive {
Active, Inactive;
static final Map<String, ActiveOrInactive> _activeOrInactive = new HashMap<String, ActiveOrInactive>();
static {
for (ActiveOrInactive activeOrInactive : ActiveOrInactive.values()) {
_activeOrInactive.put(activeOrInactive.toString(), activeOrInactive);
}
}
public static Map<String, ActiveOrInactive> getPublishedStateTypes() {
return _activeOrInactive;
}
}
According to https://docs.jboss.org/hibernate/orm/6.3/introduction/html_single/Hibernate_Introduction.html
@Enumerated(EnumType.STRING)
is mapped to varchar, except for Mysql (and maybe MariaDB) where it is mapped to an ENUM column type.
If you change:
@Column(name = "status", nullable = false)
to:
@Column(name = "status", nullable = false, columnDefinition = "varchar")
you can make hibernate understand that it's a varchar column.