Select sur un BO depuis PlatformHooks

Bonjour,
J’ai des difficultées à récuperer un record depuis la BDD dans la class PlatformHooks.

J’ai testé de plusieurs manière mais à chaque fois il ne trouve pas le record a partir de son row_id
Le record en question:
image

Le code ( 4 manière différentes):

            String centerId = g.simpleQuery(directorQuery);
            if (centerId != null && !centerId.isBlank()) {
                ObjectDB center = Grant.getSystemAdmin().getTmpObject("NamCentre");

                BusinessObjectTool boToool = new BusinessObjectTool(center);

                boToool.select(centerId);
                // Exception, log ci-joint
                boToool.getObject().setFieldValue("namCntUserDirecteurId", userId);
                boToool.validateAndUpdate();

                center.resetFilters();
                if (center.select(centerId)) {
                    // A priori false à chaque fois
                    center.setFieldValue("namCntUserDirecteurId", userId);
                    center.update();
                }

                ObjectDB namCentre = g.getTmpObject("NamCentre");
                try {
                    // Erreur, log ci-joint
                    namCentre.getTool().select(centerId);
                    namCentre.getTool().getObject().setFieldValue("namCntUserDirecteurId", userId);
                    namCentre.save();
                } catch (GetException e) {
                    AppLog.simpleError(e);
                }
                namCentre.resetFilters();
                namCentre.getField("row_id").setFilter(centerId);

                for (String[] row : namCentre.search(false)) {
                    //Array vide
                    namCentre.setFieldValue("namCntUserDirecteurId", userId);
                    namCentre.update();
                }

L’objet en quesiton
image

Quelle piste ai-je omis ?

Bonjour,

  1. Le g.getTmpObject() (ligne 19 du code collé) ne peut pas vous donner un objet fonctionnel puisque vous êtes dans le preLoadGrant et que les droits de l’utilisateur n’ont donc pas encore été chargés. Cela explique que vous obteniez un GetException en utilisant BusinessObjectTool.select : l’utilisateur n’a pas les droits.

  2. Votre première approche (l.3) est plus pertinente: on utilise en général l’utilisateur system (dont vous utilisez les droits avec Grant.getSystemAdmin()) pour les manipulations en amont du chargement du grant. Vous obtenez cependant la même exception, il est donc probable que l’utilisateur system n’ait pas les droits sur notre objet NamCentre. Vous pouvez essayer d’exclure ce cas de figure :

    • en attribuant manuellement les droits avec Grant.changeAccess

    • en mettant ajoutant un groupe de droits de type superadministrateur en profil du groupe ADMIN

Exemple avec attribution manuelle
String centerId = g.simpleQuery(directorQuery);
if (centerId != null && !centerId.isBlank()) {

    Grant sys = Grant.getSystemAdmin();
    boolean[] oldcrud = sys.changeAccess("NamCentre", false,true,true,false); // READ & UPDATE
    try{
        ObjectDB center = sys.getTmpObject("NamCentre");
        synchronized(center){
            center.resetFilters();
            center.resetValues();
            center.getTool().select(centerId);
            center.setFieldValue("namCntUserDirecteurId", userId);
            center.getTool().validateAndUpdate();
        }
    }
    catch(Exception e){
        AppLog.error(e, sys);
    }
    finally{
        // restore original rights
        sys.changeAccess("NamCentre", oldcrud);
    }
}

Cordialement,

1 Like

Merci beaucoup !

 try {
            Grant systemAdminGrant = Grant.getSystemAdmin();
            systemAdminGrant.changeAccess(NamCentre.class.getSimpleName(), new boolean[]{true, true, true, true});
            
            String centerId = systemAdminGrant.simpleQuery(directorQuery);
            ObjectDB center = Grant.getSystemAdmin().getTmpObject(NamCentre.class.getSimpleName());

            center.getTool().select(centerId);
            center.getTool().getObject().setFieldValue("namCntUserDirecteurId", userId);
            center.save();

        } catch (Exception e) {
            AppLog.debug("L'utilisateur n'est pas un directeur de centre");
        }

Est-ce qu’il convient de révoquer l’access après l’opération ?

Oui, comme dans l’exemple fourni, qui respecte mieux les bonnes pratiques. En effet, dans votre code on peut évoquer :

  • l’indentation à revoir (mais j’imagine que c’est le résultat des copiers-coller)
  • le center.getTool().getObject().setFieldValue est strictement équivalent et moins performant qu’un simple center.getFieldValue
  • le center.save() auquel on préfèrera un center.getTool().validateAndUpdate() pour travailler avec les exceptions plutôt qu’avec la valeur de retour du save.
  • l’absence de synchronized qui expose à des modifications de l’instance depuis d’autres parties du code
  • l’absence de resetValues & resetFilters (qui risque, je crois, de nuire au select)

Au cas où vous ne l’ayez simplement pas vu, il est dans mon post précédent:

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