Hi, I assume the code below lies inside a REST service implementation class.
Basically, it manipulates payload objects (UserCR, AttrPatch and so on) then invokes UserLogic for actual processing. If so, then you should remove @Transactional from such method as by doing so you are essentially breaking the transaction mechanism as managed by UserLogic. HTH Regards. On 28/11/23 11:53, GCHQDeveloper29 wrote:
Hi there, I'm hoping to gain some advice (or report a bug in the case I've not just been a fool!). I'm currently on version 3.0.4, although plan to move to 3.0.5 soon, and am using version 1.5.7 of the LDAP connector. I have a slightly different version of the following function sat behind a rest endpoint, but am observing peculiar behaviour when calling the rest endpoint (hence triggering an update in userLogic). ``` @Transactional public Response updateAttr(final UpdateAttrTO updateAttrTO, final String attribute) { // key can either be the username or the UUID of the user String key = updateAttrTO.getKey(); String attrVal = updateAttrTO.getAttrVal(); try { // getUser gets the user object, first trying by username, then by UUID User user = getUser(key); String uuid = user.getKey(); String username = user.getUsername(); // Create the patch and user update request Attr attr = new Attr.Builder(attribute) .value(attrVal) .build(); AttrPatch patch = new AttrPatch.Builder(attr) .operation(attrVal == "" ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE) .build(); UserUR userUR = new UserUR.Builder(uuid) .plainAttr(patch) .build(); // Attempt to patch the user ProvisioningResult<UserTO> provisioningResult = userLogic.update(userUR, false); return Response.ok().build(); } // Catch if a user cannot be found catch (NotFoundException e) { return Response.status(400, e.getLocalizedMessage()).build(); } // Catch any other unanticipated error catch (Exception e) { return Response.status(500, e.getLocalizedMessage()).build(); } } ``` The above function can be called as below (I use rest parameters in actuality): ``` UpdateAttrTO updateAttrTO = new UpdateAttrTO(); updateAttrTO.setKey("ExampleKey"); updateAttrTO.setAttrVal("ExampleAttrVal"); return updateAttr(updateAttrTO, "ExampleAttribute"); ``` When I do this, the value gets updated within syncopes database, however the propogation task (to an LDAP connector), updates the downstream resource with the previous value. For example, if I were to do the following for a user "user123", that does not initially have "ExampleAttribute" set, the downstream resource is always one value behind: ``` // ---- // Syncope value - N/A // Downstream LDAP resource - N/A // ---- UpdateAttrTO updateAttrTO1 = new UpdateAttrTO(); updateAttrTO1.setKey("user123"); updateAttrTO1.setAttrVal("1111"); updateAttr(updateAttrTO1, "ExampleAttribute"); // ----- // Syncope value - "1111" // Downstream LDAP resource - N/A // ----- UpdateAttrTO updateAttrTO2 = new UpdateAttrTO(); updateAttrTO2.setKey("user123"); updateAttrTO2.setAttrVal("2222"); updateAttr(updateAttrTO2, "ExampleAttribute"); // ---- // Syncope value - "2222" // Downstream LDAP resource - "1111" // ---- ``` Hopefully I explained the situation sufficiently, if not please let me know and I can try to give some more detail. Kind Regards, GCHQDeveloper29.
-- Francesco Chicchiriccò Tirasa - Open Source Excellence http://www.tirasa.net/ Member at The Apache Software Foundation Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail http://home.apache.org/~ilgrosso/