JPA:AttributeConverter

时间:2015-10-07 16:50:36

标签: java hibernate jpa orm eclipselink

我们正在开发一个连接到旧数据库的应用程序。这非常"无类型",几乎所有数据都使用字符串。更糟糕的是,这是非常均匀的:它使用不同的模式来表示日期或时间(' YYDDMM'' HHMMSS',毫秒)和布尔(' Y&#39 ; /' N',' X' /''),例如。

我们想要使用JPA(EclipseLink)和自定义转换器。问题是@Convert期望一个类实现AttributeConverter,所以我们必须为每个模式做新的类。我喜欢的是一个BooleanConverter类,它可以用值' Y' N' 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;

    ...
}

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

3 个答案:

答案 0 :(得分:1)

尝试@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;
}

答案 1 :(得分:0)

所以你的转换器的行为会有所不同,具体取决于上下文中的某些状态?我想我会尝试将上下文信息绑定到一个threadlocal变量,我可以在Converter实现中读回来。

您是否可以访问CDI实施?然后更优雅的是将您的上下文信息注入一些bean到您的Converter实现中。你提到你遗漏了一些session - 方法?也许一个@SessionScope'ed bean会帮助你。

可悲的是,转换器类中未指定@Inject。你需要像this post中提到的那样“手动”查找bean。

答案 2 :(得分:0)

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