mad*_*nce 6 spring hibernate jpa
如何为泛型实现AttributeConverter?
就像是
class JSONConverter<T> implements AtttributeConverter<T,String>{
//Here How do I get the generic class type with which I can convert a serialized object
}
Run Code Online (Sandbox Code Playgroud)
在实体类中调用转换器作为
@Column
@Convert( converter = JSONConverter.class) //How do I pass the Generic here
private SomeClass sm;
Run Code Online (Sandbox Code Playgroud)
小智 7
可以做得更简单一些,因为您不一定需要通过构造函数传递 typeReference:
public abstract class JsonConverter<T> implements AttributeConverter<T, String> {
private final TypeReference<T> typeReference = new TypeReference<T>() {};
@Resource
private ObjectMapper objectMapper;
@Override
public String convertToDatabaseColumn(T object) {
try {
return objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override
public T convertToEntityAttribute(String json) {
try {
return objectMapper.readValue(json, typeReference);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后是扩展 JsonConventer 的类,如下所示:
public class SomeClassConverter extends JsonConverter<SomeClass> { }
Run Code Online (Sandbox Code Playgroud)
我在 Eclipselink 和 Java 8 中使用了以下解决方案。一个没有立即显现出来的问题是转换器类必须直接实现 AttributeConverter(至少要与 Eclipselink 一起使用)
步骤1.定义一个通用接口来实现Object <-> String Json转换。因为接口不能包含属性,所以我定义了两个方法getInstance(),并getObjectMapper()提供对运行时所需的对象实例的转换逻辑访问。转换器类需要提供这些方法的实现。
package au.com.sfamc.fusion.commons.jpa;
import java.io.IOException;
import javax.persistence.AttributeConverter;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public interface GenericJsonAttributeConverter<X> extends AttributeConverter<X, String> {
X getInstance();
ObjectMapper getObjectMapper();
@Override
default String convertToDatabaseColumn(X attribute) {
String jsonString = "";
try {
// conversion of POJO to json
if(attribute != null) {
jsonString = getObjectMapper().writeValueAsString(attribute);
} else {
jsonString = "{}"; // empty object to protect against NullPointerExceptions
}
} catch (JsonProcessingException ex) {
}
return jsonString;
}
@Override
default X convertToEntityAttribute(String dbData) {
X attribute = null;
try {
if(StringUtils.isNoneBlank(dbData)) {
attribute = getObjectMapper().readValue(dbData, (Class<X>)getInstance().getClass());
} else {
attribute = getObjectMapper().readValue("{}", (Class<X>)getInstance().getClass());
}
} catch (IOException ex) {
}
return attribute;
}
}
Run Code Online (Sandbox Code Playgroud)
步骤 2.getObjectMapper()每个转换器类都会重复该方法实现,因此我引入了一个扩展的抽象类,GenericJsonAttributeConverter以节省在每个转换器类中实现此方法的必要性。
package au.com.sfamc.fusion.commons.jpa;
import com.fasterxml.jackson.databind.ObjectMapper;
public abstract class AbstractGenericJsonAttributeConverter<X> implements GenericJsonAttributeConverter<X> {
private static final ObjectMapper objectmapper = new ObjectMapper();
@Override
public ObjectMapper getObjectMapper() {
return AbstractGenericJsonAttributeConverter.objectmapper;
}
}
Run Code Online (Sandbox Code Playgroud)
步骤 3.为您想要转换为 Json 或从 Json 转换的每个类创建一个具体实现AbstractGenericJsonAttributeConverter,即使您想要转换的每个类都需要其自己的具体转换器类,至少您不会重复转换代码...
package au.com.sfamc.fusion.main.client;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import au.com.sfamc.fusion.commons.jpa.AbstractGenericJsonAttributeConverter;
@Converter
public class ProjectMetricsReportJsonConverter extends AbstractGenericJsonAttributeConverter<ProjectMetricsReport> implements AttributeConverter<ProjectMetricsReport, String> {
private static final ProjectMetricsReport projectMetricsReport = new ProjectMetricsReport();
@Override
public ProjectMetricsReport getInstance() {
return ProjectMetricsReportJsonConverter.projectMetricsReport;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:现在让它与 Eclipselink 一起工作的技巧很微妙,但却是必需的。除了扩展AbstractGenericJsonAttributeConverter具体实现之外,还必须直接引用implements“AttributeConverter”接口(为实现通用转换工作而付出的代价很小)
| 归档时间: |
|
| 查看次数: |
3099 次 |
| 最近记录: |