ERR_USERKEY sur objet métier dont la clé fonctionnelle est un champ document

Problem description

Bonjour,

Nous rencontrons un problème avec l’un de nos objets métier qui contient un champ de type document qui est la clé fonctionnel de l’objet.
L’anomalie décrite ci-dessous arrive de temps en temps, nous n’avons pas de mode op’ pour la reproduire mais on peut la simuler en modifiant la base de données.

Steps to reproduce

Contexte

Pour pouvoir décrire l’anomalie j’utilise :

  • une instance Simplicité 5.2.11
  • le module de démo
  • un objet métier que j’ai créé dont la clé fonctionnelle est un champ de type document.

Voici la configuration de l’objet que j’ai créé :

Constat lorsque l’anomalie est présente

Lorsque l’anomalie est présente, l’utilisateur ne peut plus créer de nouvelles pièces jointes. L’erreur suivante s’affiche :

Lorsqu’on regarde l’état de la base de données on constate que dans la table demo_pj on a une ligne dont la colonne “demo_pj_document” vaut 0.

Dans les logs, on constate l’erreur suivante lors de la création de la ligne de row_id 7 :

Pour sortir de l’anomalie je dois aller dans “Document > Documents > Synchronise les documents”.

L’état de la base de données est alors le suivant :

La ligne avec demo_pj_document = 0 a été modifié, demo_pj_document contient null à présent.

Je peux de nouveaux créer des pj :

Mode op’ pour simuler la présence de l’anomalie

  1. Créer deux pièces jointes

Table demo_pj après les créations :

Table m_document après les créations :

  1. Je supprime le document qui a le row_id 5666 :

delete from m_document where row_id = 5666;

Table m_document après suppression de 5666 :

  1. Je modifie la séquence m_document_row_id_seq :

select setval('m_document_row_id_seq', 5665);

  1. Je crée une nouvelle pj et j’enregistre :

J’ai un message qui dit que l’enregistrement c’est bien passé, mais le champ document est vide.

En BDD on constate que l’id du document pour cette nouvelle pj est 0 :

Dans les logs :

Dans la table m_document j’ai bien un nouveau document de row_id 5666 :

  1. Je ferme le formulaire :

  2. Je crée une nouvelle pj et j’enregistre :

Cette fois l’enregistrement échoue et une erreur est présente.

Conclusion

Pour être dans l’anomalie il faut qu’une pièce jointe pointe vers un document qui n’existe plus dans m_document et que la séquence m_document_row_id_seq donne un row_id qui est déjà présent dans demo_pj au niveau du champ demo_pj_document.
→ Nous ne savons pas reproduire cette anomalie sans modifier directement la BDD mais en prod ce cas peut arriver de temps en temps (on n’a pu le constater sur deux applications différentes).

Lorsqu’on est dans ce cas de figure, la première pièce jointe créée pointe vers un document de row_id 0.
→ D’après les logs et les tests que j’ai pu faire, j’ai l’impression que lors de la création de ma pièce jointe, Simplicité utilise le row_id 0 pour le document lié. Puis le document est sauvegardé dans m_document et l’id mis à jour dans ma pièce jointe pour pointer vers le document uploadé. Mais la màj de l’id dans ma pièce jointe échoue car l’id attribué au document existe déjà dans la colonne demo_pj_document de la table demo_pj. Lors de la création d’une seconde pièce jointe, j’ai l’erreur ERR_USERKEY car l’id 0 est déjà utilisé (alors qu’il ne devrait pas si c’est un id temporaire).
→ Est-il possible de renforcer le mécanisme afin d’éviter le cas ou l’id 0 est conservé, bloquant ainsi la création de nouvelles pièces jointes dans mon cas ?

C’était pas facile à expliquer, j’espère que ce que j’ai écrit est compréhensible ^^

Technical information

Instance /health

[Platform]
Status=OK
Version=5.2.11
BuiltOn=2022-07-22 22:18
Git=5.2/bc1f6e720f5df119336af65fa1b502bd40ac47d4
Encoding=UTF-8
EndpointIP=
EndpointURL=
TimeZone=UTC
SystemDate=2022-08-23 16:31:48

[Application]
ApplicationVersion=1.0.0
ContextPath=
ContextURL=
ActiveSessions=0
TotalUsers=7
EnabledUsers=5
LastLoginDate=2022-08-23 15:31:54

[Server]
ServerInfo=Apache Tomcat/9.0.65
ServerType=WEB
ServerActiveSessions=1
ServerSessionTimeout=30

[OS]
Name=Linux
Architecture=amd64
Version=5.4.0-124-generic
DockerImageName=centos7
SystemEncoding=UTF-8

[JavaVM]
Version=17.0.3
Vendor=Eclipse Adoptium
VMName=OpenJDK 64-Bit Server VM
VMVersion=17.0.3+7
ScriptEngine=rhino
ScriptEngineVersion=Rhino 1.7.13 2020 09 02
HeapFree=316088
HeapSize=618496
HeapMaxSize=2037760
TotalFreeSize=1735352

[Cache]
ObjectCache=50
ObjectCacheMax=10000
ObjectCacheRatio=0
ProcessCache=12
ProcessCacheMax=10000
ProcessCacheRatio=0
APIGrantCache=0
APIGrantCacheMax=1000
APIGrantRatio=0

[Database]
Vendor=3
ProductName=PostgreSQL
ProductVersion=11.16 (Debian 11.16-1.pgdg90+1)
DriverName=PostgreSQL JDBC Driver
DriverVersion=42.4.0
DBDate=2022-08-23 16:31:48
DBDateOffset=0
DBPatchLevel=5;P02;061b2c28d6156a42239626b53ced124f
UsingBLOBs=true

[Healthcheck]
Date=2022-08-23 16:31:48
ElapsedTime=258

Bonjour Florent,

Avant de creuser plus en détail, il n’est pas particulièrement recommandé de définir un champ document comme clé fonctionnelle. De plus, il me parait étrange d’un point de vue fonctionnel et métier que ce soit le cas.

Peux-tu nous expliquer le cas d’usage ?

Bonjour Alistair,

Dans Trustmed on a un objet “Pièces Jointes” qui est lié à l’objet “Dossiers de ruptures”. La clé fonctionnelle de l’objet “Pièces Jointes” est le document uploadé (rstPjFichier) :

image

L’utilisateur peut ainsi ajouter des pièces jointes à son dossier grâce à l’onglet “Pièce Jointes” :

Florent,

Je te conseille d’ajouter 1 ou 2 champs comprenant le nom du doc (DocumentDB.getName()) et une date d’upload par exemple qui pourront constituer la clé fonctionnelle de l’objet Pièce Jointe. Je te conseille également d’y ajouter l’id rstPjRptId et donc de retirer le document de la clé fonctionnelle.

Bonjour,

Il n’est pas possible de corriger ce defect car lié aux capacités internes des SGBD, un index unique en base ne peut pas être un document ou un blob. De plus un champ clé est sensé être recherchable au sens d’un “like”, d’une valeur ou d’un intervalle de valeurs, ce n’est pas le cas pour un document joint.

En 5.3 il ne sera plus possible de créer un champ clé de type :

  • Doc
  • Image
  • Notepad
  • HTML
  • ou long text > 4000

Ca ne marchera donc pas actuellement en 5.2 (“create unique index” qui plante en base, bug au save…). Le contrôle n’avait jamais été fait, car personne n’avait jamais paramétré cela. Il ne sera pas backporté en 5.2 car ça reste un breaking change à corriger par un designer au prochain passage en 5.3.

  • Une clé fonctionnelle / utilisateur doit nécessairement rester indexable en base (donc limitée en taille) et humainement lisible et recherchable (donc un code unique, un libellé, un numéro et une date, une référence vers une autre objet…).

  • Une clé fonctionnelle d’un objet peut être composite : constituée de plusieurs champs clés (ex nom + prénom + date de naissance)

  • Au pire lorsqu’un objet n’a pas de clé métier, il faut alors créer un champ calculé ou incrémental (comme le numéro de la commande sur la démo).

D’accord nous allons faire ça. Merci Alistair et François.

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.