From dfb7b4ceeb24b047df5117c8f5c6c1788b3bfa0e Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Thu, 10 Oct 2024 12:11:00 -0600 Subject: [PATCH] Retrieve All ODM-Managed Attributes on Update In this way, if an Entry has an operational attribute, it will be present in both the updated and existing objects so that DirContextAdapter does not compute it as a new attribute. Closes gh-446 --- .../java/org/springframework/ldap/core/LdapTemplate.java | 8 +++++++- .../java/org/springframework/ldap/itest/odm/Person.java | 8 ++++++++ .../ldap/itest/odm/PersonWithDnAnnotations.java | 8 ++++++++ .../itest/odm/LdapTemplateOdmWithDnAnnotationsITests.java | 2 ++ .../odm/LdapTemplateOdmWithNoDnAnnotationsITests.java | 2 ++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java index 1c89bf34..f73558ec 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -1674,12 +1674,18 @@ public class LdapTemplate implements LdapOperations, InitializingBean { Assert.notNull(id, String.format("Unable to determine id for entry %s", entry.toString())); - DirContextOperations context = lookupContext(id); + String[] attributes = this.odm.manageClass(entry.getClass()); + DirContextAdapter context = lookup(id, attributes, cast()); + context.setUpdateMode(true); this.odm.mapToLdapDataEntry(entry, context); modifyAttributes(context); } } + private ContextMapper cast() { + return (ctx) -> (T) ctx; + } + /** * {@inheritDoc} */ diff --git a/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/Person.java b/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/Person.java index e05da449..76bdc1e1 100644 --- a/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/Person.java +++ b/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/Person.java @@ -57,6 +57,10 @@ public class Person implements Persistable { @Attribute(name = "entryUUID", readonly = true) private String entryUuid; + // gh-446 + @Attribute(name = "creatorsName") + private String creatorsName; + @Override public Name getId() { return getDn(); @@ -123,4 +127,8 @@ public class Person implements Persistable { return this.entryUuid; } + public String getCreatorsName() { + return this.creatorsName; + } + } diff --git a/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/PersonWithDnAnnotations.java b/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/PersonWithDnAnnotations.java index 42170bbd..61b7016d 100644 --- a/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/PersonWithDnAnnotations.java +++ b/test/integration-tests/src/main/java/org/springframework/ldap/itest/odm/PersonWithDnAnnotations.java @@ -63,6 +63,10 @@ public class PersonWithDnAnnotations { @Attribute(name = "entryUUID", readonly = true) private String entryUuid; + // gh-446 + @Attribute(name = "creatorsName") + private String creatorsName; + public Name getDn() { return this.dn; } @@ -131,4 +135,8 @@ public class PersonWithDnAnnotations { return this.entryUuid; } + public String getCreatorsName() { + return this.creatorsName; + } + } diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithDnAnnotationsITests.java b/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithDnAnnotationsITests.java index b64abe4c..3028a324 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithDnAnnotationsITests.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithDnAnnotationsITests.java @@ -157,6 +157,8 @@ public class LdapTemplateOdmWithDnAnnotationsITests extends AbstractLdapTemplate person.setDesc(Arrays.asList("New Description")); String entryUuid = person.getEntryUuid(); assertThat(entryUuid).describedAs("The operational attribute 'entryUUID' was not set").isNotEmpty(); + String creatorsName = person.getCreatorsName(); + assertThat(creatorsName).describedAs("The operational attribute 'creatorsName' was not set").isNotEmpty(); this.tested.update(person); person = this.tested.findByDn(LdapUtils.newLdapName("cn=Some Person3, ou=company1, ou=Sweden"), diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithNoDnAnnotationsITests.java b/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithNoDnAnnotationsITests.java index 24e05e12..d5483750 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithNoDnAnnotationsITests.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/itest/odm/LdapTemplateOdmWithNoDnAnnotationsITests.java @@ -169,6 +169,8 @@ public class LdapTemplateOdmWithNoDnAnnotationsITests extends AbstractLdapTempla person.setDesc(Arrays.asList("New Description")); String entryUuid = person.getEntryUuid(); assertThat(entryUuid).describedAs("The operational attribute 'entryUUID' was not set").isNotEmpty(); + String creatorsName = person.getCreatorsName(); + assertThat(creatorsName).describedAs("The operational attribute 'creatorsName' was not set").isNotEmpty(); this.tested.update(person); person = this.tested.findOne(LdapQueryBuilder.query().where("cn").is("Some Person3"), Person.class);