- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我们正试图找到一种使用 JPA 持久保存枚举的可靠方法。使用@Enumerated
的常用方法是不可取的,因为重构时很容易破坏映射。每个枚举都应该有一个单独的数据库值,可以不同于枚举名称/顺序,这样您就可以安全地更改枚举的名称或内部顺序(例如,序号值)而不会破坏任何东西。例如。 this blog post 有一个关于如何实现此目的的示例,但我们认为建议的解决方案会使代码过于困惑。我们希望通过使用 JPA 2.1 中引入的新 AttributeConverter
机制来实现类似的结果。我们有一个每个枚举都应该实现的接口(interface),它定义了一个方法来获取用于将枚举存储在数据库中的值。示例:
public interface PersistableEnum {
String getDatabaseValue();
}
...
public enum SomeEnum implements PersistableEnum {
FOO("foo"), BAR("bar");
private String databaseValue;
private SomeEnum(String databaseValue) {
this.databaseValue = databaseValue;
}
public void getDatabaseValue() {
return databaseValue;
}
}
我们还有一个基本转换器,它具有将枚举转换为字符串的逻辑,反之亦然,并为每个枚举类型单独的具体转换器类(AFAIK,一个完全通用的枚举转换器是不可能实现的,这也被注意到 in this SO answer ).然后,具体转换器只需调用进行转换的基类,如下所示:
public abstract class EnumConverter<E extends PersistableEnum> {
protected String toDatabaseValue(E value) {
// Do the conversion...
}
protected E toEntityAttribute(Class<E> enumClass, String value) {
// Do the conversion...
}
}
...
@Converter(autoApply = true)
public class SomeEnumConverter extends EnumConverter<SomeEnum>
implements AttributeConverter<SomeEnum, String> {
public String convertToDatabaseColumn(SomeEnum attribute) {
return toDatabaseValue(attribute);
}
public SomeEnum convertToEntityAttribute(String dbData) {
return toEntityAttribute(SomeEnum.class, dbData);
}
}
然而,尽管这种方法在技术意义上非常有效,但仍然存在一个非常讨厌的陷阱:每当有人创建一个新的枚举类,其值需要存储到数据库中时,该人还需要记住创建新的枚举类enum 实现 PersistableEnum
接口(interface)并为其编写一个转换器类。如果没有这个,枚举将毫无问题地持久化,但转换将默认使用 @Enumerated(EnumType.ORDINAL)
,这正是我们想要避免的。我们如何防止这种情况发生?有没有办法让 JPA(在我们的例子中是 Hibernate)不默认为任何映射,但是例如如果没有在字段上定义 @Enumerated
并且找不到该类型的转换器,则抛出异常?或者我们可以创建一个“捕获所有”转换器,为所有没有自己特定转换器类的枚举调用,并且总是从那里抛出异常吗?还是我们每次都只能接受并尝试记住额外的步骤?
最佳答案
您要确保所有Enums 都是PersistableEnum 的实例。
您需要设置一个默认实体监听器(一个实体监听器,其回调适用于持久性单元中的所有实体)。
在Default Entity Listener 类中实现@PrePersist 方法并确保所有Enums 都是PersistableEnum 的实例。
关于java - 强制对枚举使用 JPA AttributeConverter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24141546/
如果我有一个 AttributeConverter 在将输入保留到数据库之前更改输入的长度,那么确保修改后的输入不超过允许的最大长度的正确方法是什么按该列(无需在转换器中对其进行硬编码)? @Colu
我正在寻找一种简单的方法来查询格式为 YYYYMMDD 的字符串类型的数据库列。这可以通过 native 查询来完成,例如: select * from TPRODUCT where to_date(
我已经创建了一个转换器,并希望从属性文件中获取 secretKey。 @Converter public class CryptoConverter implements AttributeConve
我正在尝试使用 AttributeConverter 使用 Hibernate 4.3.0 将新的 Java 8 ZonedDateTime 值存储在 MySQL 数据库(DATETIME 字段)中。
我在 spring boot 1.2.1 RELEASE 中使用 JPA AttributeConverter 并且工作正常。但是升级到spring boot 1.3.0.RELEASE后出现如下错误
我们正在开发一个连接到遗留数据库的应用程序。这是非常“无类型”的,几乎所有数据都使用字符串。更糟糕的是,它远非同质的:它对日期或时间('YYDDMM'、'HHMMSS'、毫秒)和 boolean 值(
我有一个像这样的 jpa 实体: @Entity public class RectangleEntity { @Id @GeneratedValue(strategy = Generat
我们正试图找到一种使用 JPA 持久保存枚举的可靠方法。使用@Enumerated 的常用方法是不可取的,因为重构时很容易破坏映射。每个枚举都应该有一个单独的数据库值,可以不同于枚举名称/顺序,这样您
我正在尝试解决的问题 我正在尝试为 Hibernate 实现枚举映射。到目前为止,我已经研究了可用的选项,以及 @Enumerated(EnumType.ORDINAL)和 @Enumerated(E
我有一个简单的AttributeConverter我尝试注入(inject)一个必须提供转换逻辑的对象的实现,但是 @Inject似乎不适用于这种情况。转换器类如下所示: @Converter(aut
如何实现泛型的 AttributeConverter? 类似的东西 class JSONConverter implements AtttributeConverter{ //Here How
正如 Tobias Liefke 建议的那样 here ,我已经实现了一个 AttributeConverter 来将列表值存储到一个用逗号分隔的字符串列中。 转换器类: public class L
我使用 JPA 将我的数据保存到数据库中。详细来说,我使用 Hibernate 4.3.5 作为 JPA 实现。由于性能和保持表结构简单,我不直接从对象 1:1 映射到表,而是将一些数据列表保留为对象
我正在使用 ZonedDateTime,目前使用 Spring Boot 1.3.1 和 JPA,Hibernate 使用 jadira: @Type(type = "org.jadira.usert
AttributeConverter的接口(interface)如下: public interface AttributeConverter { public Y convertToData
在 Java 应用程序和 MySql 之间进行通信时,我需要在 Map 和 JSON 字符串之间进行转换。我遇到了两个非常有前途的解决方案:AttributeConverter 和 UserType。
我有一个应用程序,过去使用 STS 和 maven 命令行都可以正常工作。在代码更改后,添加了一个新的 AttributeConverter,它不再工作了。我仍然能够使用 maven 命令行构建和运行
我自己写了一个AttributeConverter来加密和解密基于thoughts-on-java的ByteArrays看起来类似于: @Converter public class CryptoBy
我试图结合两个概念: 存储枚举,它们是实体的一对多关系(使用 @ElementCollection、@CollectionTable) 不是通过字符串或序号来保存枚举,而是通过唯一 ID(使用 @At
我想使用新的 JPA 2.1 功能来创建自定义通用枚举转换器。但在部署时我收到此错误:Caused by: org.hibernate.AssertionFailure: Could not extr
我是一名优秀的程序员,十分优秀!