93 votes

Mappage d'une colonne JSON PostgreSQL vers une propriété d'entité Hibernate

J'ai une table avec une colonne de type JSON dans ma base de données PostgreSQL (9.2). J'ai du mal à faire correspondre cette colonne à un type de champ Entity de JPA2.

J'ai essayé d'utiliser String mais lorsque j'enregistre l'entité, je reçois une exception indiquant qu'il ne peut pas convertir les caractères variables en JSON.

Quel est le type de valeur correct à utiliser lorsqu'on traite une colonne JSON ?

@Entity
public class MyEntity {

    private String jsonPayload; // this maps to a json column

    public MyEntity() {
    }
}

Une solution de contournement simple consisterait à définir une colonne de texte.

3voto

Balaban Mario Points 336

J'ai eu un problème similaire avec Postgres (javax.persistence.PersistenceException : org.hibernate.MappingException : No Dialect mapping for JDBC type : 1111) lors de l'exécution de requêtes natives (via EntityManager) qui récupéraient des champs json dans la projection bien que la classe Entity ait été annotée avec TypeDefs. La même requête traduite en HQL était exécutée sans aucun problème. Pour résoudre ce problème, j'ai dû modifier JsonPostgreSQLDialect de cette façon :

public class JsonPostgreSQLDialect extends PostgreSQL9Dialect {

public JsonPostgreSQLDialect() {

    super();

    this.registerColumnType(Types.JAVA_OBJECT, "json");
    this.registerHibernateType(Types.OTHER, "myCustomType.StringJsonUserType");
}

Où myCustomType.StringJsonUserType est le nom de la classe implémentant le type json (d'après la réponse de Tim Fulmer ci-dessus) .

2voto

Evan Carroll Points 13420

Il existe une façon plus simple de procéder, qui n'implique pas la création d'une fonction, en utilisant la fonction WITH INOUT

CREATE TABLE jsontext(x json);

INSERT INTO jsontext VALUES ($${"a":1}$$::text);
ERROR:  column "x" is of type json but expression is of type text
LINE 1: INSERT INTO jsontext VALUES ($${"a":1}$$::text);

CREATE CAST (text AS json)
  WITH INOUT
  AS ASSIGNMENT;

INSERT INTO jsontext VALUES ($${"a":1}$$::text);
INSERT 0 1

1voto

A. Gautam Points 11

Toutes les solutions ci-dessus n'ont pas fonctionné pour moi. Finalement, j'ai utilisé des requêtes natives pour insérer les données.

Étape -1 Créer une classe abstraite AbstractEntity qui implémente Persistable. avec l'annotation @MappedSuperclass (partie de javax.persistence) Step -2 Dans cette classe créez votre générateur de séquence car vous ne pouvez pas générer un séquenceur avec les requêtes natives. @Id @GeneratedValues @Column private Long seqid ;

N'oubliez pas - Votre classe d'entité doit étendre votre classe abstraite. (en aidant votre séquence à fonctionner aussi bien qu'elle peut fonctionner sur la date aussi bien (vérifier pour la date je ne suis pas sûr))

Etape- 3 Dans l'interface repo, écrivez la requête native.

value="INSERT INTO table( ?,?)values(: ?,:cast(:jsonString as json))",nativeQuery=true

Étape - 4 Cela convertira votre objet java string en json et l'insérera/stockera dans la base de données et vous pourrez également incrémenter la séquence à chaque insertion.

J'ai eu une erreur de casting lorsque j'ai travaillé avec le convertisseur. Aussi type-52 personnellement j'ai évité d'utiliser cela dans mon projet. S'il vous plaît upvote mes ans si elle fonctionne pour vous les gars.

1voto

Joseph Waweru Points 986

J'ai rencontré ce problème lorsque j'ai migré mes projets de MySQL 8.0.21 vers Postgres 13. Mon projet utilise Spring boot avec la dépendance de type Hibernate version 2.7.1. Dans mon cas, la solution était simple. enter image description here

Tout ce que j'avais à faire était de changer ça et ça a marché.

Référencé dans le Page de documentation sur les types Hibernate .

0voto

nenchev Points 57

J'ai été confronté à ce problème et je ne voulais pas activer des choses via la chaîne de connexion, et autoriser des conversions implicites. Au début, j'ai essayé d'utiliser @Type, mais comme j'utilise un convertisseur personnalisé pour sérialiser/désérialiser une carte vers/depuis JSON, je ne pouvais pas appliquer une annotation @Type. Il s'est avéré que j'avais juste besoin de spécifier columnDefinition = "json" dans mon annotation @Column.

@Convert(converter = HashMapConverter.class)
@Column(name = "extra_fields", columnDefinition = "json")
private Map<String, String> extraFields;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X