必须转换 java.util.Locale 属性

对于类型为 java.util.Locale 的属性,OpenJPA 将创建类型为 VARCHAR(254) 的列,而 EclipseLink 将创建类型为 BLOB(64000) LOGGED NOT COMPACT 的列。在 EclipseLink 中,当您引用 OpenJPA 创建的 Locale 列时,该差异将导致 java.io.CharConversionException。 要通过与 OpenJPA 相同的方式来使用 Locale 属性,请使用 EclipseLink 中的 Java 持久性类型转换器。

该规则标记类型为 java.util.Locale 的属性中非瞬态且还没有转换器的属性。 要手动迁移该问题,请遵循以下步骤:

  1. 创建与以下示例中显示的类相类似的 Converter 类。
  2. 将 converter 类添加到持久性单元定义。
  3. 通过 @Convert 注释对 java.util.Locale 字段进行注释,并将转换器属性设置为您所创建的转换器类。

例如,该规则将标记以下实体类中的 Locale 属性:

import java.util.Locale;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class LocaleEntity{
    @Id
    private int id;
    
    private Locale localeField;

}

创建转换器类。 以下示例显示了 java.util.Locale 的样本类型转换器类。

import java.util.Locale;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class LocaleConverter implements AttributeConverter<Locale, String> {

    public String convertToDatabaseColumn(Locale val) {
        return val.getLanguage() + "_" + val.getCountry()
                + "_" + val.getVariant();
    }

    public Locale convertToEntityAttribute(String str) {
        if (isNullOrEmpty(str))
            return null;
        String[] params = str.split("_", 3);
        if (params.length < 3)
            return null;
        return new Locale(params[0], params[1], params[2]);
    }

	private boolean isNullOrEmpty(String str) {
		return str==null || str.isEmpty();
	}

}

通过 @Convert 注释对 Locale 属性进行注释。

import java.util.Locale;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class LocaleEntity{
    @Id
    private int id;
    
    @Convert(converter=LocaleConverter.class)
    private Locale localeField;

}

有关此问题和其他 OpenJPA 到 EclipseLink 迁移问题的信息,请参阅 OpenJPA to EclipseLink JPA Migration: Mappings 指南。