必須轉換 java.util.Locale 屬性

對於 java.util.Locale 類型的屬性,OpenJPA 建立 VARCHAR(254) 類型的直欄,而 EclipseLink 則建立 BLOB(64000) LOGGED NOT COMPACT 類型的直欄。在 EclipseLink 中,當您參照的 Locale 直欄是由 OpenJPA 所建立時,此差異會產生 java.io.CharConversionException。 若要以 OpenJPA 的相同方式使用 Locale 屬性,請在 EclipseLink 中使用 Java 持續性類型轉換器。

此規則標示 java.util.Locale 類型的屬性,這些屬性非暫時性,且尚無轉換器。 若要手動移轉此問題,請遵循下列步驟:

  1. 建立 Converter 類別,其類似下面範例所示的類別。
  2. 將轉換器類別新增至持續性單元定義。
  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 至 EclipseLink JPA 移轉:對映手冊。