diff --git a/build.gradle b/build.gradle
index ce8c8382a6f8c695ab534e4a9f558c3305b9a4c7..34a263c2012b3e8566b8646b3663fecc0cb397ec 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,7 @@
 plugins {
     id 'java'
     id 'com.github.johnrengelman.shadow' version '8.1.1'
+    id "org.sonarqube" version "5.0.0.4638"
 }
 
 group = 'sh.libre.scim'
diff --git a/src/main/java/sh/libre/scim/core/Adapter.java b/src/main/java/sh/libre/scim/core/Adapter.java
index e9762122c1bdfba7e69029ce7295d5724acfe935..607a7e137c3ce4b1252d308cd8d2af7e2c3b4c46 100644
--- a/src/main/java/sh/libre/scim/core/Adapter.java
+++ b/src/main/java/sh/libre/scim/core/Adapter.java
@@ -13,6 +13,12 @@ import sh.libre.scim.jpa.ScimResource;
 
 import java.util.stream.Stream;
 
+/**
+ * Abstract class for converting a Keycloack {@link RoleMapperModel} into a SCIM {@link ResourceNode}.
+ *
+ * @param <M> The Keycloack {@link RoleMapperModel} (e.g. GroupModel, UserModel)
+ * @param <S> the SCIM {@link ResourceNode} (e.g. Group, User)
+ */
 public abstract class Adapter<M extends RoleMapperModel, S extends ResourceNode> {
 
     protected final Logger logger;
diff --git a/src/main/java/sh/libre/scim/core/ScimClient.java b/src/main/java/sh/libre/scim/core/ScimClient.java
index 5831bf3d8c0f7e1ca8de38504ad80b20ee10e1ff..071251bae0110c44d85b223a603c40acc2cfe496 100644
--- a/src/main/java/sh/libre/scim/core/ScimClient.java
+++ b/src/main/java/sh/libre/scim/core/ScimClient.java
@@ -14,6 +14,7 @@ import io.github.resilience4j.retry.RetryConfig;
 import io.github.resilience4j.retry.RetryRegistry;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.NoResultException;
+import jakarta.persistence.TypedQuery;
 import jakarta.ws.rs.ProcessingException;
 import org.jboss.logging.Logger;
 import org.keycloak.component.ComponentModel;
@@ -91,6 +92,10 @@ public class ScimClient implements AutoCloseable {
         return new ScimClient(scimRequestBuilder, retryRegistry, session, model);
     }
 
+    private static <M extends RoleMapperModel, S extends ResourceNode, A extends Adapter<M, S>> TypedQuery<ScimResource> findById(A adapter) {
+        return adapter.query("findById", adapter.getId());
+    }
+
     protected EntityManager getEntityManager() {
         return session.getProvider(JpaConnectionProvider.class).getEntityManager();
     }
@@ -116,7 +121,7 @@ public class ScimClient implements AutoCloseable {
         if (adapter.skip)
             return;
         // If mapping exist then it was created by import so skip.
-        if (!adapter.query("findById", adapter.getId()).getResultList().isEmpty()) {
+        if (!findById(adapter).getResultList().isEmpty()) {
             return;
         }
         Retry retry = registry.retry("create-" + adapter.getId());
@@ -148,7 +153,7 @@ public class ScimClient implements AutoCloseable {
             adapter.apply(kcModel);
             if (adapter.skip)
                 return;
-            ScimResource resource = adapter.query("findById", adapter.getId()).getSingleResult();
+            ScimResource resource = findById(adapter).getSingleResult();
             adapter.apply(resource);
             Retry retry = registry.retry("replace-" + adapter.getId());
             ServerResponse<S> response = retry.executeSupplier(() -> {
@@ -178,7 +183,7 @@ public class ScimClient implements AutoCloseable {
         adapter.setId(id);
 
         try {
-            ScimResource resource = adapter.query("findById", adapter.getId()).getSingleResult();
+            ScimResource resource = findById(adapter).getSingleResult();
             adapter.apply(resource);
 
             Retry retry = registry.retry("delete-" + id);