Проблемы @Inject в AttributeConverter в JPA 2.2/Java EE 8/Glassfish v5

JPA 2.2 должен поддерживать @Inject в AttributeConverter, как описано в спецификации:

Классы конвертера атрибутов в средах Java EE поддерживают внедрение зависимостей через контексты и API внедрения зависимостей (CDI) [ 7 ], когда CDI включен [51]. Класс преобразователя атрибутов, который использует внедрение CDI, может также определять методы обратного вызова жизненного цикла, аннотированные аннотациями PostConstruct и PreDestroy. Эти методы будут вызваны после внедрения и до уничтожения экземпляра преобразователя атрибутов соответственно.

Но когда я конвертирую свой образец конвектора JPA 2.1 в JPA 2.2, он не работает.

Оригинальный конвертер работал как Glassfish v4, так и v5:

@Converter
public class ListToStringConveter implements AttributeConverter<List<String>, String> {

//@Inject Logger log;

@Override
public String convertToDatabaseColumn(List<String> attribute) {
    if (attribute == null || attribute.isEmpty()) {
        return "";
    }
    return StringUtils.join(attribute, ",");
}

@Override
public List<String> convertToEntityAttribute(String dbData) {
    if (dbData == null || dbData.trim().length() == 0) {
        return new ArrayList<String>();
    }

    String[] data = dbData.split(",");
    return Arrays.asList(data);
}
}

По вкусу инъекционная поддержка AttributeConverter в JPA 2.2 я извлек логику преобразования в другой компонент CDI. И попытался запустить коды в Glassfish v5(Реализация Java EE 8 Reference).

@Converter(autoApply = false)
public class TagsConverter implements AttributeConverter<List<String>, String> {

//    private static final Logger LOG = Logger.getLogger(TagsConverter.class.getName());
//    
//     @Override
//    public String convertToDatabaseColumn(List<String> attribute) {
//        if (attribute == null || attribute.isEmpty()) {
//            return "";
//        }
//        return String.join( ",", attribute);
//    }
//
//    @Override
//    public List<String> convertToEntityAttribute(String dbData) {
//        if (dbData == null || dbData.trim().length() == 0) {
//            return new ArrayList<>();
//        }
//
//        String[] data = dbData.split(",");
//        return Arrays.asList(data);
//    }

    @Inject
    Logger LOG;

    @Inject
    ConverterUtils utils;

    @PostConstruct
    public void postConstruct(){
        LOG.log(Level.INFO, "calling @PostConstruct");
    }

    @PreDestroy
    public void preDestroy(){
        LOG.log(Level.INFO, "calling @PreDestroy");
    }

    @Override
    public String convertToDatabaseColumn(List<String> attribute) {
        LOG.log(Level.FINEST, "utils injected: {0}", utils != null);
        if (attribute == null || attribute.isEmpty()) {
            return "";
        }
        return utils.listToString(attribute);
    }

    @Override
    public List<String> convertToEntityAttribute(String dbData) {
        if (dbData == null || dbData.trim().length() == 0) {
            return Collections.<String>emptyList();
        }
        return utils.stringToList(dbData);
    }

}

А также ConverterUtils учебный класс.

@ApplicationScoped
public class ConverterUtils {

    public String listToString(List<String> tags) {
        return join(",", tags);
    }

    public List stringToList(String str) {
        return Arrays.asList(str.split(","));
    }
}

в TagsConverterожидаемый ConverterUtils не вводятся, и всегда становятся нулевыми, когда их вызывают, бросает NPE.

Полные коды можно найти здесь.

Обновление: я обнаружил, что создал проблему на EclipseLink bugzilla 4 года назад.

0 ответов

Другие вопросы по тегам