Te doy la bienvenida a nuestro espacio, ahora vas a encontrar la solucíon de lo que buscabas.
Solución:
Todas las respuestas me ayudaron a llegar a la solución final que está lista para JPA y no específicamente para EclipseLink o Hibernate.
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.json.Json;
import javax.json.JsonObject;
import javax.persistence.Converter;
import org.postgresql.util.PGobject;
@Converter(autoApply = true)
public class JsonConverter implements javax.persistence.AttributeConverter
private static final long serialVersionUID = 1L;
private static ObjectMapper mapper = new ObjectMapper();
@Override
public Object convertToDatabaseColumn(JsonObject objectValue)
try
PGobject out = new PGobject();
out.setType("json");
out.setValue(objectValue.toString());
return out;
catch (Exception e)
throw new IllegalArgumentException("Unable to serialize to json field ", e);
@Override
public JsonObject convertToEntityAttribute(Object dataValue)
try
if (dataValue instanceof PGobject && ((PGobject) dataValue).getType().equals("json"))
return mapper.reader(new TypeReference()
).readValue(((PGobject) dataValue).getValue());
return Json.createObjectBuilder().build();
catch (IOException e)
throw new IllegalArgumentException("Unable to deserialize to json field ", e);
Editar: ahora veo que esto es bastante Hibernate
dependiente. Pero tal vez puedas encontrar algo similar para EclipseLink
.
Solo agregaré lo que tengo como respuesta, se origina en otra respuesta SO, pero lo que sea. Esto mapeará jsonb
para JsonObject
de Google gson
, pero puede cambiarlo por otro si es necesario. Para cambiar a otra cosa, cambia nullSafeGet
, nullSafeSet
y deepCopy
métodos.
public class JsonbType implements UserType
@Override
public int[] sqlTypes()
return new int[] Types.JAVA_OBJECT ;
@Override
public Class returnedClass()
return JsonObject.class;
@Override
public boolean equals(final Object x, final Object y) y == null)
return false;
return x.equals(y);
@Override
public int hashCode(final Object x)
if (x == null)
return 0;
return x.hashCode();
@Nullable
@Override
public Object nullSafeGet(final ResultSet rs,
final String[] names,
final SessionImplementor session,
final Object owner) throws SQLException
final String json = rs.getString(names[0]);
if (json == null)
return null;
final JsonParser jsonParser = new JsonParser();
return jsonParser.parse(json).getAsJsonObject();
@Override
public void nullSafeSet(final PreparedStatement st,
final Object value,
final int index,
final SessionImplementor session) throws SQLException
if (value == null)
st.setNull(index, Types.OTHER);
return;
st.setObject(index, value.toString(), Types.OTHER);
@Nullable
@Override
public Object deepCopy(@Nullable final Object value)
if (value == null)
return null;
final JsonParser jsonParser = new JsonParser();
return jsonParser.parse(value.toString()).getAsJsonObject();
@Override
public boolean isMutable()
return true;
@Override
public Serializable disassemble(final Object value)
final Object deepCopy = deepCopy(value);
if (!(deepCopy instanceof Serializable))
throw new SerializationException(
String.format("deepCopy of %s is not serializable", value), null);
return (Serializable) deepCopy;
@Nullable
@Override
public Object assemble(final Serializable cached, final Object owner)
return deepCopy(cached);
@Nullable
@Override
public Object replace(final Object original, final Object target, final Object owner)
return deepCopy(original);
Para usar esto, haz lo siguiente:
public class SomeEntity {
@Column(name = "jsonobject")
@Type(type = "com.myapp.JsonbType")
private JsonObject jsonObject;
Además, debe configurar su dialecto para indicar que JAVA_OBJECT
= jsonb
:
registerColumnType(Types.JAVA_OBJECT, "jsonb");
Creo que encontré una analogía con UserType de Hibernate para EclipseLink.
http://www.eclipse.org/eclipselink/documentation/2.6/jpa/extensions/annotations_ref.htm#CHDEHJEB
Tienes que hacer una clase que implemente org.eclipse.persistence.mappings.converters.Converter
y realiza la conversión por usted, luego use el @Convert
anotación en cada campo en el que esté utilizando ese tipo.