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

Java Enums, JPA e Postgres enums - Come faccio a farli funzionare insieme?

In realtà ho usato un modo più semplice di quello con PGObject e Converters. Poiché in Postgres le enumerazioni vengono convertite in modo abbastanza naturale in testo da cui è necessario solo lasciargli fare ciò che sa fare meglio. Prenderò in prestito l'esempio degli stati d'animo di Arjan, se non gli dispiace:

Il tipo enum in Postgres:

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

La classe e l'enumerazione in Java:

public @Entity class Person {

  public static enum Mood {sad, ok, happy};

  @Enumerated(EnumType.STRING)
  Mood mood;

}

Quel tag @Enumerated dice che la serializzazione/deserializzazione dell'enumerazione dovrebbe essere eseguita nel testo. Senza di esso, usa int, che è più problematico di qualsiasi altra cosa.

A questo punto hai due opzioni. Tu:

  1. Aggiungi stringtype=non specificato alla stringa di connessione, come spiegato nei parametri di connessione JDBC. Ciò consente a Postgres di indovinare il tipo sul lato destro e convertire tutto in modo adeguato, poiché riceve qualcosa come 'enum =sconosciuto', che è un'espressione con cui sa già cosa fare (feed il valore ? al deserializzatore di tipo sinistro). Questa è l'opzione preferita poiché dovrebbe funzionare per tutti i semplici UDT come enum in una volta sola.

    jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
    

Oppure:

  1. Crea una conversione implicita da varchar a enum nel database. Quindi in questo secondo caso il database riceve qualche assegnazione o confronto come 'enum =varchar' e trova una regola nel suo catalogo interno dicendo che può passare il valore di destra attraverso la funzione di serializzazione di varchar seguita dalla funzione di deserializzazione di enum. Sono più passaggi di quelli necessari; e avere troppi cast impliciti nel catalogo può far sì che le query arbitrarie abbiano interpretazioni ambigue, quindi usalo con parsimonia. La creazione del cast è:

    CREA CAST (CARATTERE VARIABILE come stato d'animo) CON INOUT COME IMPLICITO;

Dovrebbe funzionare proprio con quello.