spring-projects / spring-vault

Provides familiar Spring abstractions for HashiCorp Vault
https://spring.io/projects/spring-vault
Apache License 2.0
283 stars 186 forks source link

`@KeySpace` not considered using Spring Data 3.1 #800

Closed qUser13 closed 1 year ago

qUser13 commented 1 year ago

I use org.springframework.vault:spring-vault-core:3.0.3 and have faced an issue that keyspace is always set to simple class name and value from annotation KeySpace is ignored.

Looks like the reason for this in org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity constructor updates It was

public BasicKeyValuePersistentEntity(TypeInformation<T> information,
        @Nullable KeySpaceResolver fallbackKeySpaceResolver) {

    super(information);

    Class<T> type = information.getType();
    String keySpace = AnnotationBasedKeySpaceResolver.INSTANCE.resolveKeySpace(type);

    if (StringUtils.hasText(keySpace)) {

        this.keyspace = keySpace;
        this.keyspaceExpression = detectExpression(keySpace);
    } else {

        this.keyspace = resolveKeyspace(fallbackKeySpaceResolver, type);
        this.keyspaceExpression = null;
    }
}

Now it is

public BasicKeyValuePersistentEntity(TypeInformation<T> information, @Nullable KeySpaceResolver keySpaceResolver) {
    this(information, keySpaceResolver != null ? keySpaceResolver.resolveKeySpace(information.getType()) : null);
}

See https://github.com/spring-projects/spring-data-keyvalue/blob/a46f3487835f2a048ca9d03047da6eff8712b31e/src/main/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntity.java#L55

At the same time the signature for org.springframework.vault.repository.mapping.VaultMappingContext::createPersistentEntity did not changed. See

@Override
protected <T> VaultPersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
    return new BasicVaultPersistentEntity<>(typeInformation, this.fallbackKeySpaceResolver);
}

It leads to situation when fallback key space resolver is always used which is SimpleClassNameKeySpaceResolver.

I run it during Spring Boot 3.1 upgrade, works fine with Spring Boot 2.7.5.

mp911de commented 1 year ago

Thanks for bringing this up. In Spring Data KeyValue 3.1, KeyValueMappingContext has changed its behavior. If a KeySpaceResolver is used, then it will be used instead of using the resolver as fallback. That has the consequence that VaultMappingContext, which specifies a SimpleClassNameKeySpaceResolver, resolves the keyspace from the class name and no longer from the annotation.

As workaround, you can call VaultMappingContext.setFallbackKeySpaceResolver(null) to let the infrastructure use annotations. Entities that are not annotated will resolve to the full classname instead of an uncapitalized simple name.