JPA 2.2 应该支持@Inject
in AttributeConverter
,如规范中所述:
当启用 CDI [51] 时,Java EE 环境中的属性转换器类通过上下文和依赖注入 API (CDI) [7] 支持依赖注入。使用 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);
}
}
为了体验 JPA 2.2 中的注入支持AttributeConverter
,我将转换逻辑提取到另一个 CDI bean。并尝试在 Glassfish v5(Java EE 8 参考实现)中运行代码。
@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
的没有注入,并且在调用它时总是得到 null,NPE 抛出了。
完整的代码可以在这里找到。
更新:我发现4 年前我在 EclipseLink bugzilla 上创建了一个问题。