InMemoryStoreTransaction implements DataStoreTransaction { @Override public Object getRelation(DataStoreTransaction relationTx, Object entity, String relationName, Optional<FilterExpression> filterExpression, Optional<Sorting> sorting, Optional<Pagination> pagination, RequestScope scope) { Class<?> relationClass = scope.getDictionary().getParameterizedType(entity, relationName); DataFetcher fetcher = new DataFetcher() { @Override public Object fetch(Optional<FilterExpression> filterExpression, Optional<Sorting> sorting, Optional<Pagination> pagination, RequestScope scope) { return tx.getRelation(relationTx, entity, relationName, filterExpression, sorting, pagination, scope); } }; boolean filterInMemory = scope.getNewPersistentResources().size() > 0; return fetchData(fetcher, relationClass, filterExpression, sorting, pagination, filterInMemory, scope); } InMemoryStoreTransaction(DataStoreTransaction tx); @Override void save(Object entity, RequestScope scope); @Override void delete(Object entity, RequestScope scope); @Override User accessUser(Object opaqueUser); @Override void preCommit(); @Override T createNewObject(Class<T> entityClass); @Override Object getRelation(DataStoreTransaction relationTx,
                              Object entity,
                              String relationName,
                              Optional<FilterExpression> filterExpression,
                              Optional<Sorting> sorting,
                              Optional<Pagination> pagination,
                              RequestScope scope); @Override void updateToManyRelation(DataStoreTransaction relationTx,
                                     Object entity,
                                     String relationName,
                                     Set<Object> newRelationships,
                                     Set<Object> deletedRelationships,
                                     RequestScope scope); @Override void updateToOneRelation(DataStoreTransaction relationTx,
                                    Object entity,
                                    String relationName,
                                    Object relationshipValue,
                                    RequestScope scope); @Override Object getAttribute(Object entity, String attributeName, RequestScope scope); @Override void setAttribute(Object entity, String attributeName, Object attributeValue, RequestScope scope); @Override void flush(RequestScope scope); @Override void commit(RequestScope scope); @Override void createObject(Object entity, RequestScope scope); @Override Object loadObject(Class<?> entityClass,
                      Serializable id,
                      Optional<FilterExpression> filterExpression,
                      RequestScope scope); @Override Iterable<Object> loadObjects(Class<?> entityClass,
                                        Optional<FilterExpression> filterExpression,
                                        Optional<Sorting> sorting,
                                        Optional<Pagination> pagination,
                                        RequestScope scope); @Override void close();  }
@Test public void testTransactionRequiresInMemoryFilterDuringGetRelation() { FilterExpression expression = new InPredicate(new Path(Book.class, dictionary, "genre"), "Literary Fiction"); when(scope.getNewPersistentResources()).thenReturn(Sets.newHashSet(mock(PersistentResource.class))); when(wrappedTransaction.supportsFiltering(eq(Book.class), any())).thenReturn(DataStoreTransaction.FeatureSupport.FULL); when(wrappedTransaction.getRelation(eq(inMemoryStoreTransaction), eq(author), eq("books"), eq(Optional.empty()), eq(Optional.empty()), eq(Optional.empty()), eq(scope))).thenReturn(books); Collection<Object> loaded = (Collection<Object>) inMemoryStoreTransaction.getRelation( inMemoryStoreTransaction, author, "books", Optional.of(expression), Optional.empty(), Optional.empty(), scope); verify(wrappedTransaction, times(1)).getRelation( eq(inMemoryStoreTransaction), eq(author), eq("books"), eq(Optional.empty()), eq(Optional.empty()), eq(Optional.empty()), eq(scope)); assertEquals(2, loaded.size()); assertTrue(loaded.contains(book1)); assertTrue(loaded.contains(book3)); }