6 votes

JOOQ ignore les colonnes de la base de données avec des valeurs par défaut

Il semble que JOOQ ignore complètement les valeurs par défaut des colonnes de la base de données. L'objet ActiveRecord n'est pas mis à jour et il ne saute pas cette colonne lors de l'INSERT. Au lieu de cela, il essaie de lui donner la valeur NULL, ce qui échoue avec les colonnes NOT NULL.

Exemple :

CREATE TABLE bug (
  foo int,
  bar int not null default 42
);

  BugRecord b = jooq.newRecord(BUG);
  b.setFoo(3);
  b.store();          

  assertNotNull(b.getBar()); // fails

  Record r = jooq.select().from(BUG).fetchOne();
  assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails

  // DataMapper pattern
  Bug b = new Bug();
  b.setFoo(3);
  bugDao.insert(b); // Fails because it tries to set "bar" to NULL

Le comportement que j'attendrais est que le newRecord() initialise toutes les variables par défaut avec les valeurs korrekt (bien que je comprenne que cela puisse être difficile si le résultat est le fruit d'une fonction personnalisée :-)) ou que l'INSERT INTO n'insère pas toutes les colonnes non modifiées avec les valeurs par défaut et que l'INSERT INTO soit suivi d'un SELECT qui récupère les valeurs existantes dans la base de données (similaire à un RETURNING).

S'agit-il vraiment d'un bogue ou d'une limitation, ou bien ai-je oublié une option de configuration, etc. qui permet d'utiliser des colonnes "not null default" ?

10voto

Lukas Eder Points 48046

Vous avez relevé quelques points (qui concernent tous la version 3.1 de jOOQ et les versions précédentes) :

Renvoi des valeurs par défaut des insertions :

BugRecord b = jooq.newRecord(BUG);
b.setFoo(3);
b.store();          

assertNotNull(b.getBar()); // fails

Ce serait en effet une fonctionnalité très appréciable. Actuellement, jOOQ ne récupère que les valeurs des colonnes IDENTITY. Vous pouvez utiliser la fonction INSERT .. RETURNING ou la syntaxe UPDATE .. RETURNING pour choisir explicitement quelles colonnes doivent être renvoyées après une insertion ou une mise à jour. Mais il serait bien mieux de pouvoir le faire dans le cadre d'opérations CRUD normales.

Ce point avait également été mentionné dans este hilo . La demande de fonctionnalité correspondante est la suivante #1859 .

Vous pouvez contourner ce problème en appelant

b.refresh();             // Refresh all columns
b.refresh(BUG.BAR, ...); // Refresh only some columns

Insertion de NULL vs. insertion de DEFAULTs à travers UpdatableRecord :

Record r = jooq.select().from(BUG).fetchOne();
assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails

Il s'agit à mon avis d'un bogue. Les opérations CRUD de jOOQ devraient être DEFAULT valeur sûre. Seules les valeurs qui ont été définies explicitement avant l'émission d'un store() / insert() / update() doit être rendue dans le code SQL généré. J'ai enregistré #2698 pour cela.

Insertion de NULL vs. insertion de DEFAULTs à travers DAO :

// DataMapper pattern
Bug b = new Bug();
b.setFoo(3);
bugDao.insert(b); // Fails because it tries to set "bar" to NULL

Belle prise. Il s'agit d'un problème non trivial à résoudre / à améliorer, car un POJO n'est pas livré avec un indicateur interne "changed" / "dirty" par colonne. Il n'est donc pas possible de connaître la signification d'une colonne null dans un POJO.

D'autre part, jOOQ sait déjà si une colonne est nullable. Si jOOQ conservait également des métadonnées sur la présence d'une colonne DEFAULT sur une colonne, il pourrait en déduire que la combinaison NOT NULL DEFAULT devrait conduire :

INSERT INTO bug(foo, bar)
VALUES(3, DEFAULT)

Et pour

UPDATE bug SET bar = DEFAULT WHERE foo = 3

Je me suis inscrit

  • #2699 : Ajouter des métadonnées au code généré
  • #2700 : Exploitation des métadonnées susmentionnées dans SQL à partir des DAO

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