使用以下数据库组件并在Sping Boot 3(Hibernate 6)中删除@Type和@Typedef注解,当数据库也为该列使用Enum类型时,如何将枚举作为String持久化在数据库中。
数据库示例:
CREATE TYPE TEST_TYPE AS ENUM ('TESTA','TESTB');
CREATE TABLE test_table (
id INT NOT NULL PRIMARY KEY,
type TEST_TYPE NOT NULL
);
以下实体
@Entity
@Table(name = "test_table")
public class TestTableEntity
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private TestType tenantId;
}
此操作失败并返回错误,因为它试图将其作为字符串而不是枚举类型持久化。
所有其他参考资料都使用hypersistence-utils库hibernate-types-62。但是,我不需要依赖于外部utils库。
其他的解决方案很笨拙,需要为枚举实现一个新的层次结构。
更简单的解决方案是什么?
2条答案
按热度按时间6jjcrrmo1#
您可以使用ColumnTransformers来修改Hibernate生成的SQL。
这是实体的工作示例:
如果它是另一个模式的一部分,您可能需要
如果您检查生成的SQL,这将使用@Enumerated注解将TestType作为字符串传递。然后ColumnTransformer将添加用于写入的强制转换,允许DB的插入/更新查询为预期的列提供正确的参数类型。
在返回的过程中,由于我们已经将@Enumerated配置为使用String,Hibernate将根据存储的String计算出选择并返回哪个Enum。
这是一个简单的一行程序,不需要编写自定义的UserType或引入库来支持Enum。
gojuced72#
从Hibernate 6.2开始,Hibernate默认在MySQL上使用
enum
类型。https://docs.jboss.org/hibernate/orm/6.2/migration-guide/migration-guide.html#ddl-implicit-datatype-enum
例如,下面的代码:
生成以下DDL:
所以你不需要在这里做任何事情,只要升级到6.2就可以了。
然而,这还没有在PostgreSQL中实现,我猜这就是你正在使用的(你没有指定)。建议添加这个的问题是:
https://hibernate.atlassian.net/browse/HHH-16125