I have an interface that extends CrudRepository, and every time I save an object with a key that already exists, it overwrites the existing object with the new one. How can I override save
so that it checks if an object with that key already exists?
I have already tried the following, but it did not work:
public interface CustomRepo {
public Channel save(Channel channel);
}
public class RepositoryImpl implements CustomRepo {
@Autowired
private DynamoDBMapper mapper;
public Channel save(Channel channel){
channel.setId(UUID.randomUUID().toString());
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expectedAttributes =
ImmutableMap.<String, ExpectedAttributeValue>builder()
.put(channel.getUrl(), new ExpectedAttributeValue(false))
.put(channel.getTitle(), new ExpectedAttributeValue(false))
.build();
saveExpression.setExpected(expectedAttributes);
saveExpression.setConditionalOperator(ConditionalOperator.AND);
try {
mapper.save(channel, saveExpression);
} catch (ConditionalCheckFailedException e) {
System.err.println("Item with URL {} already exists. Cannot overrwrite."+ channel.getUrl());
System.err.println(e.getMessage());
}
return channel;
}
public interface ChannelRepository extends CrudRepository<Channel, String>, CustomRepo {
@EnableScan
List<Channel> findByTitle(String title);
@Override
@EnableScan
List<Channel> findAll();
List<Channel> findByUrl(String url);
}
Problem: I understand the problem statement as "all the existing non-key attributes are replaced with new value" rather than the URL and TITLE attributes that you are trying to update.
There are two ways to resolve this problem without overriding the save()
method.
1) SaveBehavior can be set appropriately to update the attributes accordingly. In your code, you have used the default UPDATE
save behavior. You can use UPDATE_SKIP_NULL_ATTRIBUTES
save behavior, so that it doesn't update the NULL attributes in model object (in your case, it is channel).
You can also look at APPEND_SET
which is a further extension of UPDATE_SKIP_NULL_ATTRIBUTES
for SET data type.
Sample Code:-
DynamoDBMapperConfig dynamoDBMapperConfig = new DynamoDBMapperConfig(SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES);
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient, dynamoDBMapperConfig);
dynamoDBMapper.save(order);
UPDATE (default) : UPDATE will not affect unmodeled attributes on a save operation and a null value for the modeled attribute will remove it from that item in DynamoDB. Because of the limitation of updateItem request, the implementation of UPDATE will send a putItem request when a key-only object is being saved, and it will send another updateItem request if the given key(s) already exists in the table.
APPEND_SET treats scalar attributes (String, Number, Binary) the same as UPDATE_SKIP_NULL_ATTRIBUTES does. However, for set attributes, it will append to the existing attribute value, instead of overriding it. Caller needs to make sure that the modeled attribute type matches the existing set type, otherwise it would result in a service exception.
UPDATE_SKIP_NULL_ATTRIBUTES is similar to UPDATE, except that it ignores any null value attribute(s) and will NOT remove them from that item in DynamoDB. It also guarantees to send only one single updateItem request, no matter the object is key-only or not.
DynamoDBMapperConfig SaveBehavior
2) The UpdateItemSpec
with table.updateItem
can be used to update few attributes for a specific key
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.