spring-data-mongodb 3.4.0 have a beautiful @Update annotation support for jpa repositories.
But how can i pass arrayFilters and other options, supported by https://www.mongodb.com/docs/manual/reference/method/db.collection.update/ ?
Here is my working manual example:
public @NotNull Comment addComment(String id, String cid, String lid, String sid, Comment comment) {
// Add comment
JwtUser user = userService.getCurrentUser().orElseThrow(() ->
new SodixException("Can't get current user"));
EditorUser author = EditorUser.builder()
.id(user.getExternalId())
.username(user.getUsername())
.firstName(user.getFirstName())
.lastName(user.getLastName())
.build();
CommentEntity commentToSave = new CommentEntity();
commentToSave.setId(ProjectIdUtil.generateCommentId());
commentToSave.setCreatedAt(LocalDateTime.now());
commentToSave.setAuthor(author);
commentToSave.setMessage(comment.getMessage());
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(id));
query.addCriteria(Criteria.where("chapters").elemMatch(
Criteria.where("_id").is(cid).and("lessons").elemMatch(
Criteria.where("_id").is(lid).and("sections").elemMatch(
Criteria.where("_id").is(sid)
)
)
));
Update update = new Update();
update.addToSet("chapters.$[c].lessons.$[l].sections.$[s].comments", commentToSave);
update.filterArray("c._id", cid);
update.filterArray("l._id", lid);
update.filterArray("s._id", sid);
var result = mongoTemplate.updateFirst(query, update, ProjectEntity.class);
if (result.getModifiedCount() < 1) {
throw new RuntimeException("Comment wasn't added");
}
}
Here is what i expect to run using repository @Update annotation, but it's not working yet:
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.Update;
...
@Repository
public interface ProjectRepository extends MongoRepository<ProjectEntity, String> {
...
@Query("{ _id : ?0, chapters : {$elemMatch : {_id: ?1, lessons: {$elemMatch: {_id: ?2, 'sections._id': ?3}}}}}")
@Update("{$set : { 'chapters.$[c].lessons.$[l].sections.$[s].comments' : ?4 }, $arrayFilters: {'c._id': ?1, 'l._id': ?2, 's._id': ?3}}")
long addComment(String id, String cid, String lid, String sid, CommentEntity comment);
...
}
Error i've got is:
com.mongodb.MongoWriteException: Write operation error on server localhost:27017. Write error: WriteError{code=2, message='No array filter found for identifier 'c' in path 'chapters.$[c].lessons.$[l].sections.$[s].comments'', details={}}.
Thanks for the help!