【问题标题】:JPA: Parameterized instances of AttributeConverterJPA:AttributeConverter 的参数化实例
【发布时间】:2016-01-05 00:40:53
【问题描述】:

我们正在开发一个连接到旧数据库的应用程序。这是非常“无类型”的,几乎所有数据都使用字符串。更糟糕的是,它远非同质:它使用不同的日期或时间模式('YYDDMM'、'HHMMSS'、毫秒)和布尔值('Y'/'N'、'X'/''),用于例子。

我们想使用 JPA (EclipseLink) 和自定义转换器。问题是@Convert 需要一个实现AttributeConverter 的类,所以我们必须为每个模式创建新的类。我想要的是一个 BooleanConverter 类,它可以用值 'Y'/'N' 或 'X'/' ' 来实例化。

这显然超出了 JPA 规范,但也许可以使用 EclipseLink 注释/配置。查看其@Convert 注释,可以通过名称指定转换器。如果我可以注册 ynBooleanConverterxSpaceBooleanConverter,这听起来不错:

// Unfortunately, this method does not exist :(
Session.addConverter('ynBooleanConverter', new BooleanConverter("Y", "N")); 

@Entity
public class MyEntity {

    @Convert("ynBooleanConverter")
    private Boolean myBoolean;

    ...
}

有可能吗?我们还有哪些其他选择?

【问题讨论】:

  • 你适合使用JPA 2.1转换器吗?可以从 eclipselink 2.5 版获得?
  • 我可以使用最新版本的 EclipseLink,但我不知道如何解决。

标签: java hibernate jpa orm eclipselink


【解决方案1】:

这个线程太晚了,但这里有一个blog post,它显示了如何编写 JPA 转换器。有用于 String 和 LocalDate 转换的工作代码。

【讨论】:

    【解决方案2】:

    所以您的转换器的行为会根据上下文中的某些状态而有所不同?我想我会尝试将上下文信息绑定到一个线程局部变量,我可以在 Converter 实现中读回该变量。

    您可以访问 CDI 实施吗?然后将一些带有上下文信息的 bean 注入到 Converter 实现中会更加优雅。您提到您缺少一些session-Methods?也许@SessionScope'ed bean 会帮助你。

    遗憾的是,@Inject 没有在转换器类中指定。您需要像 this 帖子中提到的那样“手动”查找 bean。

    【讨论】:

    • 转换器的行为不取决于状态,而是取决于正在转换的实际字段。对于使用字符串保存的日期,我有几种不同的模式。我不想创建这么多类,但只创建一个。
    【解决方案3】:

    试试@ObjectTypeConverter:

    @Entity
    @ObjectTypeConverters({
        @ObjectTypeConverter(name = "ynBooleanConverter", objectType = Boolean.class, dataType = String.class, 
            conversionValues = { 
            @ConversionValue(objectValue = "true", dataValue = "Y"), 
            @ConversionValue(objectValue = "false", dataValue = "N") }),
        @ObjectTypeConverter(name = "xSpaceBooleanConverter", objectType = Boolean.class, dataType = String.class, 
            conversionValues = { 
            @ConversionValue(objectValue = "true", dataValue = "X"), 
            @ConversionValue(objectValue = "false", dataValue = " ") }),
    })
    public class MyEntity {
    
        @Convert("ynBooleanConverter")
        private boolean ynBoolean;
    
        @Convert("xSpaceBooleanConverter")
        private boolean xSpaceBoolean;
    }
    

    【讨论】:

    • 谢谢。这仅适用于布尔值,但不适用于不同格式的日期。
    • 我猜您必须实现自己的注释才能实现该转换。我怀疑 EclipseLink 或 JPA 是否支持该逻辑。​​
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多