DATACOUCH-186 - Index-backed methods safe from deleted stales

This commit ensures that methods in the template and the repository base classes are correctly ignoring documents that have been deleted but are still identified by the view due to using weak consistency (Stale.TRUE).

FindByView in template now ignores null rows in its result list. It also correctly forces the includeDocs parameter in order not to risk a bad transcoding of the document (javadoc clarified).

DeleteAll in the repository CRUD implementation will correctly detect attempts at deleting a non-existing document (DocumentDoesNotExistException is also correctly mapped to a Spring Data exception now).

DeleteAll behavior with DataRetrievalFailureException is tested in RepositoryIndexUsageTest.
This commit is contained in:
Simon Baslé
2016-01-08 16:57:53 +01:00
parent d81dc9aacc
commit c589a13699
6 changed files with 73 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ package org.springframework.data.couchbase.repository;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
@@ -11,6 +12,7 @@ import java.util.List;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.error.DocumentDoesNotExistException;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.view.ViewQuery;
import com.couchbase.client.java.view.ViewResult;
@@ -19,6 +21,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.query.Consistency;
@@ -39,8 +42,10 @@ public class RepositoryIndexUsageTest {
public void initMocks() {
ViewRow mockCountRow1 = mock(ViewRow.class);
when(mockCountRow1.value()).thenReturn("100");
when(mockCountRow1.id()).thenReturn("id1");
ViewRow mockCountRow2 = mock(ViewRow.class);
when(mockCountRow2.value()).thenReturn("200");
when(mockCountRow2.id()).thenReturn("id2");
List<ViewRow> allCountRows = Arrays.asList(mockCountRow1, mockCountRow2);
ViewResult mockCountResult = mock(ViewResult.class);
@@ -164,4 +169,20 @@ public class RepositoryIndexUsageTest {
String statement = query.getString("statement");
assertTrue("Expected " + expectedLimitClause + " in " + statement, statement.contains(expectedLimitClause));
}
@Test
public void testDeleteAllSwallowsDocumentDoesNotExistException() {
doThrow(new DataRetrievalFailureException("ignored", new DocumentDoesNotExistException())).when(couchbaseOperations).remove("id1");
doThrow(new DataRetrievalFailureException("thrown")).when(couchbaseOperations).remove("id2");
try {
repository.deleteAll();
fail("Expected DataRetrievalFailureException on id2");
} catch (DataRetrievalFailureException e) {
if (!"thrown".equals(e.getMessage())) {
fail("DataRetrievalFailureException caused by DocumentDoesNotExistException should have been ignored");
}
}
verify(couchbaseOperations).remove("id1");
verify(couchbaseOperations).remove("id2");
}
}