Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Jpa Json Converter
package sample.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.google.common.reflect.TypeToken;
import sample.json.Json;
import org.springframework.util.StringUtils;
import javax.annotation.Nonnull;
import javax.persistence.AttributeConverter;
import java.io.IOException;
public abstract class JpaJsonConverter<TAttribute> implements AttributeConverter<TAttribute, String> {
private final TypeToken<TAttribute> type = new TypeToken<TAttribute>(getClass()) {
};
private ObjectReader reader;
@Override
public String convertToDatabaseColumn(TAttribute attribute) {
if (attribute == null) {
return null;
}
try {
return serialize(attribute);
} catch (JsonProcessingException e) {
throw new RuntimeException("cannot serialize attribute " + attribute, e);
}
}
protected String serialize(@Nonnull TAttribute attribute) throws JsonProcessingException {
return mapper().writeValueAsString(attribute);
}
@Nonnull
public ObjectMapper mapper() {
return Json.getMapper();
}
@Override
public TAttribute convertToEntityAttribute(String dbData) {
if (dbData == null || StringUtils.isEmpty(dbData)) {
return valueForEmptyColumn();
}
try {
return deserialize(dbData);
} catch (IOException e) {
throw new RuntimeException("cannot deserialize attribute: " + type + " from: " + dbData, e);
}
}
public TAttribute valueForEmptyColumn() {
return null;
}
protected TAttribute deserialize(@Nonnull String dbData) throws IOException {
ObjectReader reader = getReader();
return reader.readValue(dbData);
}
private ObjectReader getReader() {
//constructing reader takes roughly ~20% deserialization time
ObjectMapper mapper = mapper();
if (reader == null) {
reader = mapper.readerFor(mapper.constructType(type.getType()));
}
return reader;
}
}
package sample.json;
class EntityChild {
String name;
}
class Entity {
@Convert(converter = EntityChildrenListConverter.class)
List<EntityChild> children = new ArrayList<>();
public static class EntityChildrenListConverter extends JpaJsonConverter<List<EntityChild>> {
}
}
@mnatsakanyank

This comment has been minimized.

Copy link

mnatsakanyank commented Sep 26, 2017

Hi, I got to your code because I am having an issue with Jsons we are storing in the columns. Basically I have a question, is it possible to query DB with EntityChild using standard Spring jpa repositories?
e.g repository.findByChildren(List children)

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.