sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Son posibles los tipos personalizados de JPA (EclipseLink)?

Al recorrer SO, encontré muchas preguntas como esta con respecto a los tipos JSON o XML para mapear en Postgres. Parece que nadie se ha enfrentado al problema de leer del tipo personalizado de Postgres, así que aquí está la solución tanto para leer como para escribir utilizando el mecanismo de conversión de tipo JPA puro.

El controlador JDBC de Postgres asigna todos los atributos para tipos desconocidos (a Java) en el objeto org.postgresql.util.PGobject, por lo que es suficiente para hacer un convertidor para este tipo. Aquí hay un ejemplo de entidad:

@Entity
public class Course extends AbstractEntity {
    @Column(name = "course_mapped", columnDefinition = "json")
    @Convert(converter = CourseMappedConverter.class)
    private CourseMapped courseMapped;  // have no idea why would you use String json instead of the object to map

    // getters and setters
}

Aquí el ejemplo del convertidor:

@Converter
public class CourseMappedConverter implements AttributeConverter<CourseMapped, PGobject> {
    @Override
    public PGobject convertToDatabaseColumn(CourseMapped courseMapped) {
        try {
            PGobject po = new PGobject();
            // here we tell Postgres to use JSON as type to treat our json
            po.setType("json");
            // this is Jackson already added as dependency to project, it could be any JSON marshaller
            po.setValue((new ObjectMapper()).writeValueAsString(courseMapped));
            return po;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public CourseMapped convertToEntityAttribute(PGobject po) {
        try {
            return (new ObjectMapper()).readValue(po.getValue(),CourseMapped.class);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Si realmente necesita apegarse a la representación String JSON en su entidad, puede hacer un convertidor como este para el tipo String

implements AttributeConverter<String, PGobject>

Aquí hay una prueba de concepto muy sucia (aunque funcional), también usa la serialización de objetos falsos para decirle a JPA que el objeto se cambió si fue

https://github.com/sasa7812/psql-cache-evict-POC