PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Os tipos personalizados JPA (EclipseLink) são possíveis?


Andando pelo SO, encontrei muitas perguntas como essa sobre os tipos JSON ou XML para mapeamento no Postgres. Parece que ninguém enfrentou o problema de ler do tipo Postgres personalizado, então aqui está a solução para ler e escrever usando o mecanismo de conversão de tipo JPA puro.

O driver Postgres JDBC mapeia todos os atributos para tipos desconhecidos (para Java) no objeto org.postgresql.util.PGobject, então é suficiente fazer um conversor para este tipo. Aqui está um exemplo de entidade:
@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
}

Aqui o exemplo do conversor:
@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;
        }
    }
}

Se você realmente precisa manter a representação String JSON em sua entidade, você pode fazer um conversor como este para o tipo String
implements AttributeConverter<String, PGobject>

Aqui está uma prova de conceito muito suja (embora funcionando), ela também usa serialização de objeto falso para informar ao JPA que o objeto foi alterado se fosse

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