diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java index 3c7219c2..4be29447 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java @@ -32,6 +32,7 @@ import org.springframework.data.keyvalue.core.KeyValueOperations; import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; +import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.TimeToLive; import org.springframework.data.redis.core.convert.KeyspaceConfiguration; @@ -722,6 +723,50 @@ public boolean exists(Example example) { return count(example) > 0; } + @Override + public boolean existsById(ID id) { + Assert.notNull(id, "The given id must not be null"); + + // Use direct Jedis EXISTS command for optimal performance + // Construct key properly for composite IDs + String fullKey = getKeyForId(id); + + return Boolean.TRUE.equals(modulesOperations.template().execute((RedisCallback) connection -> connection + .keyCommands().exists(fullKey.getBytes()))); + } + + private String getKeyForId(Object id) { + // Get the mapping context's entity info + RedisEnhancedPersistentEntity persistentEntity = (RedisEnhancedPersistentEntity) mappingContext + .getRequiredPersistentEntity(metadata.getJavaType()); + + String stringId; + + // Handle composite IDs + if (persistentEntity.isIdClassComposite()) { + BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(id); + List idParts = new ArrayList<>(); + for (RedisPersistentProperty idProperty : persistentEntity.getIdProperties()) { + Object propertyValue = wrapper.getPropertyValue(idProperty.getName()); + if (propertyValue != null) { + idParts.add(propertyValue.toString()); + } + } + stringId = String.join(":", idParts); + } else { + stringId = mappingConverter.getConversionService().convert(id, String.class); + } + + // Apply ID filters if they exist + var maybeIdentifierFilter = indexer.getIdentifierFilterFor(metadata.getJavaType()); + if (maybeIdentifierFilter.isPresent()) { + IdentifierFilter filter = (IdentifierFilter) maybeIdentifierFilter.get(); + stringId = filter.filter(stringId); + } + + return getKeyspace() + stringId; + } + // ------------------------------------------------------------------------- // Query By Example Fluent API - QueryByExampleExecutor // ------------------------------------------------------------------------- diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisEnhancedRepository.java b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisEnhancedRepository.java index adcf3c9a..8ff0ce65 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisEnhancedRepository.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisEnhancedRepository.java @@ -22,6 +22,7 @@ import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; import org.springframework.data.redis.core.PartialUpdate; +import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.convert.RedisData; import org.springframework.data.redis.core.convert.ReferenceResolverImpl; @@ -596,6 +597,50 @@ public boolean exists(Example example) { return count(example) > 0; } + @Override + public boolean existsById(ID id) { + Assert.notNull(id, "The given id must not be null"); + + // Use direct Jedis EXISTS command for optimal performance + // Construct key properly for composite IDs + String fullKey = getKeyForId(id); + + return Boolean.TRUE.equals(modulesOperations.template().execute((RedisCallback) connection -> connection + .keyCommands().exists(fullKey.getBytes()))); + } + + private String getKeyForId(Object id) { + // Get the mapping context's entity info + RedisEnhancedPersistentEntity persistentEntity = (RedisEnhancedPersistentEntity) mappingConverter + .getMappingContext().getRequiredPersistentEntity(metadata.getJavaType()); + + String stringId; + + // Handle composite IDs + if (persistentEntity.isIdClassComposite()) { + BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(id); + List idParts = new ArrayList<>(); + for (RedisPersistentProperty idProperty : persistentEntity.getIdProperties()) { + Object propertyValue = wrapper.getPropertyValue(idProperty.getName()); + if (propertyValue != null) { + idParts.add(propertyValue.toString()); + } + } + stringId = String.join(":", idParts); + } else { + stringId = mappingConverter.getConversionService().convert(id, String.class); + } + + // Apply ID filters if they exist + var maybeIdentifierFilter = indexer.getIdentifierFilterFor(metadata.getJavaType()); + if (maybeIdentifierFilter.isPresent()) { + IdentifierFilter filter = (IdentifierFilter) maybeIdentifierFilter.get(); + stringId = filter.filter(stringId); + } + + return getKeyspace() + stringId; + } + // ------------------------------------------------------------------------- // Query By Example Fluent API - QueryByExampleExecutor // -------------------------------------------------------------------------