From 3d1c794d63cd1cbce94ff577d4b4c352b9212bf9 Mon Sep 17 00:00:00 2001 From: vcrescia Date: Fri, 10 Jul 2026 15:36:29 +0200 Subject: [PATCH 1/3] [SYNCOPE-1982] Improve query perfomance on OraclePlainSchemaRepoExtImpl --- .../repo/OraclePlainSchemaRepoExtImpl.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java index d7f253165b3..12113d96988 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java @@ -22,13 +22,12 @@ import jakarta.persistence.Query; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO; +import org.apache.syncope.core.persistence.common.dao.AbstractSearchDAO; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; import org.apache.syncope.core.persistence.jpa.entity.JPARealm; @@ -37,6 +36,15 @@ public class OraclePlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { protected static final String HAS_ATTRS_QUERY = "SELECT COUNT(id) AS counts FROM %TABLE% " + "WHERE JSON_EXISTS(plainAttrs, '$[*]?(@.schema == \"%SCHEMA%\")')"; + protected static String hasAttrQueryWithValue(final String table, final PlainSchema schema) { + return new StringBuilder("SELECT COUNT(id) FROM "). + append(table). + append(" WHERE JSON_EXISTS(plainAttrs, '$[*]?(@.schema == \""). + append(schema.getKey()).append("\" && @.uniqueValue.").append(AbstractSearchDAO.key(schema.getType())). + append(" == $value)' PASSING ?1 AS \"value\") AND id <> ?2"). + toString(); + } + protected final PlainSchemaDAO plainSchemaDAO; public OraclePlainSchemaRepoExtImpl( @@ -60,16 +68,8 @@ public boolean existsPlainAttrUniqueValue( final PlainSchema schema, final PlainAttrValue attrValue) { - Query query = entityManager.createNativeQuery( - "SELECT COUNT(id) FROM " - + JPARealm.TABLE + "," - + OracleJPAAnySearchDAO.from(plainSchemaDAO.findById(schema.getKey()). - orElseThrow(() -> new NotFoundException("PlainSchema " + schema.getKey()))) - + " WHERE " + schema.getKey() + ".uniqueValue=?1 AND id <> ?2"); - query.setParameter(1, attrValue.getValue()); - query.setParameter(2, realmKey); - - return ((Number) query.getSingleResult()).longValue() > 0; + return doExistsPlainAttrUniqueValue(JPARealm.TABLE, schema, + attrValue.getValue(), realmKey); } @Override @@ -79,14 +79,17 @@ public boolean existsPlainAttrUniqueValue( final PlainSchema schema, final PlainAttrValue attrValue) { - Query query = entityManager.createNativeQuery( - "SELECT COUNT(id) FROM " - + new SearchSupport(anyUtils.anyTypeKind()).table().name() + "," - + OracleJPAAnySearchDAO.from(plainSchemaDAO.findById(schema.getKey()). - orElseThrow(() -> new NotFoundException("PlainSchema " + schema.getKey()))) - + " WHERE " + schema.getKey() + ".uniqueValue=?1 AND id <> ?2"); - query.setParameter(1, attrValue.getValue()); - query.setParameter(2, anyKey); + return doExistsPlainAttrUniqueValue(new SearchSupport(anyUtils.anyTypeKind()).table().name(), schema, + attrValue.getValue(), anyKey); + } + + protected boolean doExistsPlainAttrUniqueValue(final String table, final PlainSchema schema, + final String attrValue, final String attrKey) { + + Query query = entityManager.createNativeQuery(hasAttrQueryWithValue(table, schema)); + + query.setParameter(1, attrValue); + query.setParameter(2, attrKey); return ((Number) query.getSingleResult()).longValue() > 0; } From 0bdc76476f68fdf98761229cd921d7bdca7e2b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 10 Jul 2026 16:00:35 +0200 Subject: [PATCH 2/3] Reflow --- .../jpa/OraclePersistenceContext.java | 3 +- .../repo/OraclePlainSchemaRepoExtImpl.java | 62 ++++++++++--------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java index d49afa29b47..99b5ebacf30 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java @@ -103,9 +103,8 @@ public RealmSearchDAO realmSearchDAO( public PlainSchemaRepoExt plainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final @Lazy ExternalResourceDAO resourceDAO, - final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { - return new OraclePlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, plainSchemaDAO, entityManager); + return new OraclePlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java index 12113d96988..37e9183fb43 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java @@ -22,12 +22,11 @@ import jakarta.persistence.Query; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.common.dao.AbstractSearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; import org.apache.syncope.core.persistence.jpa.entity.JPARealm; @@ -36,25 +35,12 @@ public class OraclePlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { protected static final String HAS_ATTRS_QUERY = "SELECT COUNT(id) AS counts FROM %TABLE% " + "WHERE JSON_EXISTS(plainAttrs, '$[*]?(@.schema == \"%SCHEMA%\")')"; - protected static String hasAttrQueryWithValue(final String table, final PlainSchema schema) { - return new StringBuilder("SELECT COUNT(id) FROM "). - append(table). - append(" WHERE JSON_EXISTS(plainAttrs, '$[*]?(@.schema == \""). - append(schema.getKey()).append("\" && @.uniqueValue.").append(AbstractSearchDAO.key(schema.getType())). - append(" == $value)' PASSING ?1 AS \"value\") AND id <> ?2"). - toString(); - } - - protected final PlainSchemaDAO plainSchemaDAO; - public OraclePlainSchemaRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, - final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { super(anyUtilsFactory, resourceDAO, entityManager); - this.plainSchemaDAO = plainSchemaDAO; } @Override @@ -62,14 +48,38 @@ public boolean hasAttrs(final PlainSchema schema) { return hasAttrs(schema, HAS_ATTRS_QUERY, StringUtils.EMPTY); } + protected boolean existsPlainAttrUniqueValue( + final String table, + final PlainSchema schema, + final String attrValue, + final String attrKey) { + + String queryString = new StringBuilder("SELECT COUNT(id) FROM ").append(table). + append(" WHERE "). + append("JSON_EXISTS(plainAttrs, '$[*]?(@.schema == \"").append(schema.getKey()).append("\" "). + append("&& @.uniqueValue.").append(OracleJPAAnySearchDAO.key(schema.getType())).append(" == $value)' "). + append("PASSING ?1 AS \"value\") AND id <> ?2"). + toString(); + + Query query = entityManager.createNativeQuery(queryString); + + query.setParameter(1, attrValue); + query.setParameter(2, attrKey); + + return ((Number) query.getSingleResult()).longValue() > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final String realmKey, final PlainSchema schema, final PlainAttrValue attrValue) { - return doExistsPlainAttrUniqueValue(JPARealm.TABLE, schema, - attrValue.getValue(), realmKey); + return existsPlainAttrUniqueValue( + JPARealm.TABLE, + schema, + attrValue.getValue(), + realmKey); } @Override @@ -79,18 +89,10 @@ public boolean existsPlainAttrUniqueValue( final PlainSchema schema, final PlainAttrValue attrValue) { - return doExistsPlainAttrUniqueValue(new SearchSupport(anyUtils.anyTypeKind()).table().name(), schema, - attrValue.getValue(), anyKey); - } - - protected boolean doExistsPlainAttrUniqueValue(final String table, final PlainSchema schema, - final String attrValue, final String attrKey) { - - Query query = entityManager.createNativeQuery(hasAttrQueryWithValue(table, schema)); - - query.setParameter(1, attrValue); - query.setParameter(2, attrKey); - - return ((Number) query.getSingleResult()).longValue() > 0; + return existsPlainAttrUniqueValue( + new SearchSupport(anyUtils.anyTypeKind()).table().name(), + schema, + attrValue.getValue(), + anyKey); } } From fa243c93d2f42581702ae998cac0bf17b7e5b66a Mon Sep 17 00:00:00 2001 From: vcrescia Date: Fri, 10 Jul 2026 18:00:38 +0200 Subject: [PATCH 3/3] Fix tests --- .../jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java index 37e9183fb43..51050bb4f83 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java @@ -78,7 +78,7 @@ public boolean existsPlainAttrUniqueValue( return existsPlainAttrUniqueValue( JPARealm.TABLE, schema, - attrValue.getValue(), + attrValue.getValue().toString(), realmKey); } @@ -92,7 +92,7 @@ public boolean existsPlainAttrUniqueValue( return existsPlainAttrUniqueValue( new SearchSupport(anyUtils.anyTypeKind()).table().name(), schema, - attrValue.getValue(), + attrValue.getValue().toString(), anyKey); } }