Это звучит как-то так c должно быть легко, но почему-то я не могу понять, как это сделать.
Используя Javers, как я могу получить текущее состояние репозитория?
Пример: у меня есть три символа, один из которых обновляется. Теперь я хочу запросить список всех символов в том виде, в каком они есть в настоящее время:
public class JaversMemoryRepositoryTest {
private static final String AUTHOR_NAME = "Luther Lansfeld";
private static Javers javersRepository;
GameCharacter sylvia;
GameCharacter bokay;
GameCharacter cyrus;
@BeforeEach
public void setUpJaversRepository() {
javersRepository = JaversBuilder.javers().build();
sylvia = GameCharacters.sylvia();
javersRepository.commit(AUTHOR_NAME, sylvia);
sylvia.name = "Sylvia the Atomic";
javersRepository.commit(AUTHOR_NAME, sylvia);
bokay= GameCharacters.bokay();
javersRepository.commit(AUTHOR_NAME, bokay);
cyrus= GameCharacters.cyrus();
javersRepository.commit(AUTHOR_NAME, cyrus);
}
@Test
public void queryShouldFindLatestVersionOfEachCharacter() {
JqlQuery entryQuery = QueryBuilder.byClass(GameCharacter.class).build();
List<Shadow<GameCharacter>> gameCharacterShadowList
= javersRepository.findShadows(entryQuery);
assertEquals(3, gameCharacterShadowList.size());
}
}
Однако этот тест не проходит (получил 4, ожидалось 3), потому что я получаю две тени для Сильвии.
Я знаю, что, вероятно, я мог бы решить эту проблему с помощью функции, которая выполняет итерацию по тени, разделяет их по идентификатору и оставляет только ту, которая имеет самую последнюю версию, но почему-то это кажется излишним для чего-то настолько базового c, что я уверен что у Джавера это должно быть где-то.
Может быть, что-то вроде:
JqlQuery entryQuery = QueryBuilder.byClass(GameCharacter.class).withLatestVersion().build();
... кроме того, что этого не существует. Но речь идет о том, что я здесь пытаюсь сделать.
Или противоположность:
JqlQuery entryQuery = QueryBuilder.byClass(GameCharacter.class).withVersion(1).build();
... который получает самую старую версию каждого GameCharacter. Я уже пробовал withVersion(-1)
для этого, но, очевидно, Javers не считает версии с конца.
Мы будем очень благодарны за любые отзывы по этому поводу.
EDIT : Вот тестовый пример, который в настоящее время дает сбой, поскольку предполагаемое поведение не реализовано, но хорошо воспроизводит вариант использования:
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
import org.javers.core.*;
import org.javers.core.metamodel.annotation.Id;
import org.javers.repository.jql.*;
import org.javers.shadow.Shadow;
import org.junit.jupiter.api.*;
public class GetLatestVersionTest {
private static final String FIRST_STRING = "This string should be in the end result";
private static final String SECOND_STRING = "This string will get overwritten with a newer version";
private static final String THIRD_STRING = "This string should also be in the end result";
private static final String FOURTH_STRING = "This string should be in the end result as well";
private static final String AUTHOR_NAME = "Test Author";
@Test
public void shouldRetrieveOnlyLatestVersionsOfAllObjects() {
Javers javers = JaversBuilder.javers().build();
StringContainer firstObject = new StringContainer(FIRST_STRING);
javers.commit(AUTHOR_NAME, firstObject);
StringContainer secondObject = new StringContainer(SECOND_STRING);
javers.commit(AUTHOR_NAME, secondObject);
StringContainer thirdObject = new StringContainer(THIRD_STRING);
javers.commit(AUTHOR_NAME, thirdObject);
secondObject.string = FOURTH_STRING;
javers.commit(AUTHOR_NAME, secondObject);
//At this point, some logic is needed that will only query the latest version
JqlQuery entryQuery = QueryBuilder.byClass(StringContainer.class).withVersion(-1).build();
List<Shadow<StringContainer>> mostRecentShadows = javers.findShadows(entryQuery);
assertEquals(3, mostRecentShadows.size());
List<String> mostRecentStrings = new ArrayList<>();
for(Shadow<StringContainer> shadow : mostRecentShadows) {
mostRecentStrings.add(shadow.get().string);
}
assertTrue(mostRecentStrings.contains(FIRST_STRING));
assertFalse(mostRecentStrings.contains(SECOND_STRING));
assertTrue(mostRecentStrings.contains(THIRD_STRING));
assertTrue(mostRecentStrings.contains(FOURTH_STRING));
}
}
class StringContainer {
@Id
public String string;
public StringContainer(String string) {
this.string = string;
}
}
Зависимости Gradle для этого:
plugins {
id 'java-library-distribution'
}
repositories {
jcenter()
}
dependencies {
// Use JUnit test framework
testCompile("org.junit.jupiter:junit-jupiter:5.6.0")
testCompile("org.junit.platform:junit-platform-runner:1.6.0")
//Logging
compile 'commons-logging:commons-logging:1.2'
compile 'log4j:log4j:1.2.17'
compile 'org.slf4j:slf4j-log4j12:1.7.25'
compile 'commons-logging:commons-logging:1.2'
//JaVers
compile 'org.javers:javers-core:5.10.0'
compile 'org.javers:javers-persistence-mongo:5.10.0'
}