Konieczna jest konwersja atrybutów java.util.Locale

W przypadku atrybutów typu java.util.Locale w interfejsie OpenJPA tworzona jest kolumna typu VARCHAR(254), a w interfejsie EclipseLink – kolumna typu BLOB (64000) LOGGED NOT COMPACT. W interfejsie EclipseLink różnica ta powoduje wystąpienie wyjątku java.io.CharConversionException podczas odwoływania się do kolumny Locale, która została utworzona przez interfejs OpenJPA. Aby używać atrybutu Locale w taki sam sposób, jak w interfejsie OpenJPA, w interfejsie EclipseLink należy użyć konwertera typu trwałości Java.

Ta reguła powoduje oznaczenie atrybutów typu java.util.Locale, które nie są przejściowe i nie mają jeszcze konwertera. Aby przeprowadzić ręczną migrację tego problemu, wykonaj następujące kroki:

  1. Utwórz klasę Converter podobną do klasy przedstawionej w poniższym przykładzie.
  2. Dodaj klasę konwertera do definicji jednostki trwałości.
  3. Oznacz pole java.util.Locale adnotacją @Convert i ustaw atrybut konwertera na utworzoną klasę konwertera.

Na przykład reguła ta powoduje oznaczenie atrybutu Locale w następującej klasie jednostki:

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;

}

Utwórz klasę konwertera. Poniżej przedstawiono przykładową klasę konwertera typu dla klasy 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();
	}

}

Należy oznaczyć atrybut Locale adnotacją @Convert.

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;

}

Informacje na ten temat oraz na temat innych problemów z migracją interfejsu OpenJPA do interfejsu EclipseLink zawiera podręcznik Migracja interfejsu JPA ze środowiska OpenJPA do EclipseLink: Odwzorowania.