spring-data-dynamodb icon indicating copy to clipboard operation
spring-data-dynamodb copied to clipboard

DeleteByIdAndAttr is not working

Open rmckinnon opened this issue 7 years ago • 2 comments

Expected Behavior

When calling the repository.deleteByIdAndSomeAttribute doesn't work when the SomeAttribute is the primary sort key.

Actual Behavior

A org.socialsignin.spring.data.dynamodb.exception.BatchDeleteException is thrown with the following stacktrace:

org.socialsignin.spring.data.dynamodb.exception.BatchDeleteException: Processing of entities failed!; nested exception is com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 8GO7K4Q4AV4OA14MF45MQKPEDFVV4KQNSO5AEMVJF66Q9ASUAAJG)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_181]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_181]
	at org.socialsignin.spring.data.dynamodb.utils.ExceptionHandler.repackageToException(ExceptionHandler.java:40) ~[spring-data-dynamodb-5.0.3.jar:5.0.3]
	at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$DeleteExecution.execute(AbstractDynamoDBQuery.java:268) ~[spring-data-dynamodb-5.0.3.jar:5.0.3]
	at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:311) ~[spring-data-dynamodb-5.0.3.jar:5.0.3]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
....

Steps to Reproduce the Problem

  1. Create DynamoDB with a primary sort key defined. In my case the primary partition key is "id" and the primary sort key is "childId"
  2. Create some records in DynmoDB
  3. Using the String Data conventions extend the repository to delete by id and childId

Excerpt:

@EnableScan
public interface ProgramCrudRepository extends CrudRepository<Program, String> {
    void deleteByIdAndChildId(String id, String childId);
}
  1. Invoke the deleteByIdAndChildId

Specifications

  • Spring Data DynamoDB Version: 5.0.3 (2.0)
  • Spring Data Version: 2.0.9-RELEASE
  • AWS SDK Version: 1.11.407
  • Java Version: 1.8.0_181
  • Platform Details: Mac OS X 10.13.6

rmckinnon avatar Oct 01 '18 10:10 rmckinnon

I just created a test case for the described scenario: https://github.com/derjust/spring-data-dynamodb/pull/208/files#diff-dcdb5f59762ba17e758ce60997071885R196

If I understand correctly, the given situation is that id is the Hash key and childId is the Range key. As with the entity model itself, DynamoDB's structure and the way spring-data expects doesn't perfectly align: The deleteById (Id as the conceptual thing represented by two fields on the DynamoDB side but as a distinct entity class on the spring-data side) on the repository must be used - as per the referenced example.

Otherwise the childId is considered a regular attribute - which is not the case as it marked as part of the (conceptual) id

derjust avatar Oct 11 '18 04:10 derjust

Updated the wiki.

derjust avatar Oct 11 '18 04:10 derjust