java.util.Locale attributes must be converted

For attributes of type java.util.Locale, OpenJPA creates a column of type VARCHAR(254), whereas EclipseLink creates a column of type BLOB(64000) LOGGED NOT COMPACT. In EclipseLink, this difference causes a java.io.CharConversionException when you reference a Locale column that was created by OpenJPA. To use the Locale attribute in the same manner as OpenJPA, use a Java persistence type converter in EclipseLink.

This rule flags attributes of type java.util.Locale that are not transient and do not already have a converter. To manually migrate this issue, follow these steps:

  1. Create a Converter class similar to the class shown in the following example.
  2. Add the converter class to the persistence unit definition.
  3. Annotate the java.util.Locale field with the @Convert annotation, and set the converter attribute to the converter class that you created.

For example, this rule flags the Locale attribute in the following entity class:

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;

}

Create a converter class. The following example shows a sample type converter class for 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();
	}

}

Annotate the Locale attribute with the @Convert annotation.

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;

}

For information about this issue and other OpenJPA to EclipseLink migration issues, see the OpenJPA to EclipseLink JPA Migration: Mappings guide.