Document haschanged retourne toujours true sans changement de document

On a la liste éditable suivante :


Les deux champs libellé et pièce jointe sont modifiables.
On souhaite avoir dans l’attribut Date la dernière modification sur la pièce jointe

On a essayé dans un post update(code ci dessous) de récuperer si l’attribut pièce jointe a été change en utilisant getField(document_field).haschanged() mais ça retourne toujours vrai quand la liste éditable contient un seul élément même si le document n’a pas été changé

Ce que résulte à avoir l’attribut Date modifié même si on change seulement le libelle ( ce changement aura lieu seulement si on a un seul élément dans la liste sinon pour 2 éléments et plus has changed renvoie les bonnes valeurs)

Technical information

Instance /health

[Platform]
Status=OK
Version=5.2.34
BuiltOn=2023-03-13 16:54
Git=5.2/8cf8688af7cd3e007a96621540535e34c4f3abf2
Encoding=UTF-8
EndpointIP=169.254.132.4
EndpointURL=http://87b862703bc2:8080
TimeZone=UTC
SystemDate=2023-05-26 15:55:48

[Application]
ApplicationVersion=2.3.31
ContextPath=
ContextURL=https://agent-recette.ladom.fr
ActiveSessions=2
TotalUsers=16
EnabledUsers=14
LastLoginDate=2023-05-26 13:11:25

[Server]
ServerInfo=Apache Tomcat/9.0.73
ServerType=WEB
ServerActiveSessions=2
ServerSessionTimeout=30

[OS]
Name=Linux
Architecture=amd64
Version=5.10.164.1-1.cm1
DockerImageName=centos7
SystemEncoding=UTF-8

[JavaVM]
Version=17.0.6
Vendor=Eclipse Adoptium
VMName=OpenJDK 64-Bit Server VM
VMVersion=17.0.6+10
ScriptEngine=rhino
ScriptEngineVersion=Rhino 1.7.13 2020 09 02
HeapFree=188323
HeapSize=949248
HeapMaxSize=1703936
TotalFreeSize=943011

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

[Database]
Vendor=3
ProductName=PostgreSQL
ProductVersion=13.10
DriverName=PostgreSQL JDBC Driver
DriverVersion=42.5.4
DBDate=2023-05-26 15:55:48
DBDateOffset=0
DBPatchLevel=5;P02;14f8034ce5a285931ca480a5451ce96e
UsingBLOBs=false

[Healthcheck]
Date=2023-05-26 15:55:48
ElapsedTime=34
 	@Override
	public String postUpdate() {
		if(getField(FIELD_JUSTIF_COMP_PIECEJOINTE).hasChanged()) {
				String rowId = getRowId();
	
				AppLog.info(getClass(), "docComplDate()", "rowid postUpdate : " + rowId, null);
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
				String localDate = LocalDateTime.now().format(formatter);
				AppLog.info(getClass(), "docComplDate()", "localdate : " + localDate, null);
	
				BusinessObjectTool objT = this.getTool();
				if (this.select(getRowId())) {
					AppLog.info(getClass(), "docComplDate()", "setFieldValue : " + localDate + " to rowid : " + getRowId(), null);
					try {
						this.setFieldValue(FIELD_JUSTIF_COMP_DATE, localDate);
						objT.validateAndSave();
					} catch (Exception e) {
						AppLog.error("Erreur lors de la validation de la date", e, null);
					}
				}
		}
		return super.postUpdate();
	}

[/details]

Autre Problème rencontré

On a voulu récupérer le path du document dans init update (pour le comparer avec celui dans le post update) mais bizarrement même si le document existe on a cette erreur :

2023-05-26 15:26:55,758|SIMPLICITE|INFO||http://87b862703bc2:8080||INFO|system|com.simplicite.objects.ladnext.LadJustificatifsComplementaires|erreur()||Event: get path du doc id: 24449 , msg : Cannot invoke "com.simplicite.util.DocumentDB.getPath()" because the return value of "com.simplicite.util.ObjectField.getDocument()" is null
2023-05-26 15:26:55,494|SIMPLICITE|INFO||http://87b862703bc2:8080||INFO|designer|com.simplicite.objects.ladnext.LadJustificatifsComplementaires|initUpdate()||Evénement: get path : LadJustificatifsComplementaires/ladJustifComplPieceJointe/0/70/sample.pdf

pour l’objet métier ci dessous, un path a été récuperer mais pas le deuxième

Bonjour,

Votre code génère une boucle infinie.
Il faut mettre à jour votre champ via un simple setValue avant de l’enregistrer (postValidate, preSave ou preUpdate). Inutile de refaire un save sur le même record !

// postValidate
if (field.hasChanged())
   field2.setValue(Tool.getCurrentDatetime());

Si dans un postSave/Update vous refaites un save/validateAndSave… sur this, vous allez repasser par le save/update et donc le postSave/Update… On peut le faire pour des cas rares (ou il faut avoir le commit confirmé pour mettre à jour autre chose en cascade) mais en veillant à le faire qu’une seule fois via une instance particulière et en testant que ce n’est pas elle-même.

Sinon pourquoi ne pas directement créer un champ en lecture seule qui affiche le champ updated_dt (en nom de colonne) et retirer tout ce code ? Le timestamp Simplicité est déjà là pour ça.

Merci pour votre retour,

On n’a pas utilisé par le champ updated_dt car le besoin est de tracer la date de changement d’un seul attribut (“pièce jointe” dans notre cas) et non pas la date de modification de toute la ligne.

Détecter un changement de document est potentiellement couteux.

Simplicité teste dans l’ordre pour le hasChanged d’un document simple :

  • si le document est nouveau ou supprimé
  • si l’id du document à changé (field.getValue != getOldValue)
  • si la date du documents a changé (getOldDocument.getLastUpdate != getDocument.getLastUpdate)
  • et enfin si les contenus sont strictement identiques (monte en mémoire les 2 documents)

Donc afficher updated_dt est aussi une façon d’éviter ce traitement surtout que votre objet ne contient qu’un document et un libellé.

Merci Francois pour ces explications,

Une dernière question, pourquoi ce bug ne se reproduit sauf si on a une donnée (un seul ligne) par contre si on a plusieurs documents ajoutés on n’a pas ça ?

Bonjour @Francois

En tant que client nous nous attendons à ce qu’une fonctionnalité ait le même comportement, qu’il y ait 1 élément ou “n” éléments.

Quand est-ce qu’il serait possible d’avoir une solution sachant que notre client est dans l’attente d’une correction pour vendredi svp ?

Cordialement,

Silvère Virlot
CDP Orange pour LADOM

Il n’y aura aucun correctif vendredi.
Merci de répondre à toutes nos questions car de notre côté il n’y a aucun bug reproductible. Donc aucune anomalie qualifiée à corriger. Nos tests ont montré que le hasChanged fonctionne bien dans un usage nominal (par exemple un save simple sur une ressource = le fichier source n’a pas changé):

  • quid de votre “save dans un postSave” = avec risque de boucle infinie dans vos livrables qui a déjà fini en cellule de crise il y a 6 mois avec vos infra en accusant Simplicité d’instabilité, de bug aléatoire.

  • avez vous modifié le code comme indiqué ? ne pas faire de postSave mais un preSave avec uniquement un setValue ?

  • et debugué ce que valent getValue != getOlfvalue, et getOldDocument().getLastUpdate() != getDocument.getLastUpdate()

si le hasChanged retourne “vrai” à tord il faut le démonter avec un cas reproductible (sur la démo par exemple).

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