本文介绍了是否可以为JPA编写一个通用的枚举转换器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个用于存储任何枚举为UPPERCASE的JPA的转换器。我们遇到的某些枚举不符合惯例,只使用大写字母,直到它们被重构为止,我仍然存储未来的值。

I wanted to write a Converter for JPA that stores any enum as UPPERCASE. Some enums we encounter do not follow yet the convention to use only Uppercase letters so until they are refactored I still store the future value.

我到目前为止: p>

What I got so far:

package student;

public enum StudentState {

    Started,
    Mentoring,
    Repeating,
    STUPID,
    GENIUS;
}

我想开始被存储为STARTED等等。

I want "Started" to be stored as "STARTED" and so on.

package student;

import jpa.EnumUppercaseConverter;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Entity
@Table(name = "STUDENTS")
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long mId;

    @Column(name = "LAST_NAME", length = 35)
    private String mLastName;

    @Column(name = "FIRST_NAME", nullable = false, length = 35)
    private String mFirstName;

    @Column(name = "BIRTH_DATE", nullable = false)
    @Temporal(TemporalType.DATE)
    private Date mBirthDate;

    @Column(name = "STUDENT_STATE")
    @Enumerated(EnumType.STRING)
    @Convert(converter = EnumUppercaseConverter.class)
    private StudentState studentState;

}

转换器目前看起来像这样:

the converter currently looks like this:

package jpa;


import javax.persistence.AttributeConverter;
import java.util.EnumSet;

public class EnumUppercaseConverter<E extends Enum<E>> implements AttributeConverter<E, String> {

    private Class<E> enumClass;

    @Override
    public String convertToDatabaseColumn(E e) {
        return e.name().toUpperCase();
    }

    @Override
    public E convertToEntityAttribute(String s) {
        // which enum is it?
        for (E en : EnumSet.allOf(enumClass)) {
            if (en.name().equalsIgnoreCase(s)) {
                return en;
            }
        }
        return null;
    }

}

什么不行?不知道什么是enumClass在运行时。我不知道在@Converter注释中将这些信息传递给转换器的方法。

what will not work is that I do not know what enumClass will be at runtime. And I could not figure out a way to pass this information to the converter in the @Converter annotation.

所以有一种方法可以向转换器添加参数或作弊位?还是有另一种方式?

So is there a way to add parameters to the converter or cheat a bit? Or is there another way?

我使用EclipseLink 2.4.2

I'm using EclipseLink 2.4.2

谢谢!

推荐答案

您需要做的是编写一个通用基类,然后针对要保留的每个枚举类型进行扩展。然后在 @Converter 注释中使用扩展类型:

What you need to do is write a generic base class and then extend that for each enum type you want to persist. Then use the extended type in the @Converter annotation:

public abstract class GenericEnumUppercaseConverter<E extends Enum<E>> implements AttributeConverter<E, String> {
    ...
}

public FooConverter
    extends GenericEnumUppercaseConverter<Foo> 
    implements AttributeConverter<Foo, String> // See Bug HHH-8854
{
    public FooConverter() {
        super(Foo.class);
    }
}

其中 Foo 是您要处理的枚举。

where Foo is the enum you want to handle.

另一种方法是定义一个自定义注释,修补JPA提供程序以识别此注释。这样,您可以在构建映射信息并将所需的枚举类型提供给纯粹的转换器时检查字段类型。

The alternative would be to define a custom annotation, patch the JPA provider to recognize this annotation. That way, you could examine the field type as you build the mapping information and feed the necessary enum type into a purely generic converter.

相关:



  • https://hibernate.atlassian.net/browse/HHH-8854

这篇关于是否可以为JPA编写一个通用的枚举转换器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 21:54