PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Sono possibili tipi personalizzati JPA (EclipseLink)?

Esplorando SO ho trovato molte domande come questa sui tipi JSON o XML per la mappatura in Postgres. Sembra che nessuno abbia affrontato il problema della lettura dal tipo Postgres personalizzato, quindi ecco la soluzione sia per la lettura che per la scrittura utilizzando il meccanismo di conversione del tipo JPA puro.

Il driver Postgres JDBC mappa tutti gli attributi per i tipi sconosciuti (su Java) nell'oggetto org.postgresql.util.PGobject, quindi è sufficiente creare un convertitore per questo tipo. Ecco un esempio di entità:

@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
}

Ecco l'esempio del convertitore:

@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 hai davvero bisogno di attenerti alla rappresentazione String JSON nella tua entità, puoi creare un convertitore come questo per il tipo String

implements AttributeConverter<String, PGobject>

Ecco una prova di concetto molto sporca (sebbene funzionante), utilizza anche la serializzazione di oggetti falsi per dire a JPA che l'oggetto è stato modificato se lo era

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