#146 - Added tests and simplified condition.
Added tests to verify behaviour. In order to improve testability querying was extracted into package private method. The condition avoiding the IN-queries with empty parameter lists was simplified and made less lenient. Original pull request: #147.
This commit is contained in:
@@ -90,7 +90,7 @@ public class EnversRevisionRepositoryImpl<T, ID, N extends Number & Comparable<N
|
||||
Class<T> type = entityInformation.getJavaType();
|
||||
AuditReader reader = AuditReaderFactory.get(entityManager);
|
||||
|
||||
List<Number> revisions = reader.getRevisions(type, id);
|
||||
List<Number> revisions = getRevisions(id, type, reader);
|
||||
|
||||
if (revisions.isEmpty()) {
|
||||
return Optional.empty();
|
||||
@@ -129,7 +129,7 @@ public class EnversRevisionRepositoryImpl<T, ID, N extends Number & Comparable<N
|
||||
|
||||
Class<T> type = entityInformation.getJavaType();
|
||||
AuditReader reader = AuditReaderFactory.get(entityManager);
|
||||
List<? extends Number> revisionNumbers = reader.getRevisions(type, id);
|
||||
List<? extends Number> revisionNumbers = getRevisions(id, type, reader);
|
||||
|
||||
return revisionNumbers.isEmpty() ? Revisions.none()
|
||||
: getEntitiesForRevisions((List<N>) revisionNumbers, id, reader);
|
||||
@@ -144,14 +144,15 @@ public class EnversRevisionRepositoryImpl<T, ID, N extends Number & Comparable<N
|
||||
|
||||
Class<T> type = entityInformation.getJavaType();
|
||||
AuditReader reader = AuditReaderFactory.get(entityManager);
|
||||
List<Number> revisionNumbers = reader.getRevisions(type, id);
|
||||
List<Number> revisionNumbers = getRevisions((ID) id, (Class<T>) type, reader);
|
||||
boolean isDescending = RevisionSort.getRevisionDirection(pageable.getSort()).isDescending();
|
||||
|
||||
if (isDescending) {
|
||||
Collections.reverse(revisionNumbers);
|
||||
}
|
||||
|
||||
if (revisionNumbers.isEmpty() || pageable.getOffset() > revisionNumbers.size()) {
|
||||
if (
|
||||
pageable.getOffset() >= revisionNumbers.size()) {
|
||||
return Page.empty(pageable);
|
||||
}
|
||||
|
||||
@@ -166,6 +167,10 @@ public class EnversRevisionRepositoryImpl<T, ID, N extends Number & Comparable<N
|
||||
return new PageImpl<Revision<N, T>>(revisions.getContent(), pageable, revisionNumbers.size());
|
||||
}
|
||||
|
||||
List<Number> getRevisions(ID id, Class<T> type, AuditReader reader) {
|
||||
return reader.getRevisions(type, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entities in the given revisions for the entitiy with the given id.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.envers.repository.support;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.envers.AuditReader;
|
||||
import org.hibernate.envers.boot.internal.EnversService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
|
||||
import org.springframework.data.repository.history.support.RevisionEntityInformation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for EversRevisionRepositoryImpl.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public class EnversRevisionRepositoryImplUnitTests {
|
||||
|
||||
private static final int NON_EXISTING_ID = -999;
|
||||
|
||||
JpaEntityInformation<?, ?> entityInformation = mock(JpaEntityInformation.class);
|
||||
RevisionEntityInformation revisionEntityInformation = mock(RevisionEntityInformation.class);
|
||||
SessionImplementor session = mock(SessionImplementor.class, RETURNS_DEEP_STUBS);
|
||||
EnversService enversService = mock(EnversService.class, RETURNS_DEEP_STUBS);
|
||||
EntityManager entityManager = mock(EntityManager.class);
|
||||
|
||||
|
||||
@Before
|
||||
public void mockHibernateInfrastructure() {
|
||||
|
||||
when(entityInformation.getJavaType()).thenReturn((Class) DummyEntity.class);
|
||||
|
||||
when(enversService.getEntitiesConfigurations().isVersioned(any(String.class))).thenReturn(true);
|
||||
|
||||
when(session.isOpen()).thenReturn(true);
|
||||
when(session.getFactory().getServiceRegistry().getService(EnversService.class)).thenReturn(enversService);
|
||||
|
||||
when(entityManager.getDelegate()).thenReturn(session);
|
||||
}
|
||||
|
||||
@Test // #146
|
||||
public void findRevisionShortCircuitsOnEmptyRevisionList() {
|
||||
|
||||
failOnEmptyRevisions();
|
||||
|
||||
EnversRevisionRepositoryImplUnderTest<?, Object, ?> repository = new EnversRevisionRepositoryImplUnderTest<>(entityInformation, revisionEntityInformation, entityManager);
|
||||
|
||||
repository.findRevisions(-999, PageRequest.of(0, 5));
|
||||
}
|
||||
|
||||
private void failOnEmptyRevisions() {
|
||||
|
||||
// simulate failure to query with empty revisions list as Postgres does.
|
||||
when(enversService.getRevisionInfoQueryCreator().getRevisionsQuery(any(Session.class), eq(Collections.emptySet()))
|
||||
.getResultList()).thenThrow(HibernateException.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension for the {@link EnversRevisionRepositoryImpl} that skips accessing the AuditReader and always returns an empty List.
|
||||
*/
|
||||
private class EnversRevisionRepositoryImplUnderTest<T, ID, N extends Number & Comparable<N>>
|
||||
extends EnversRevisionRepositoryImpl<T, ID, N> {
|
||||
|
||||
EnversRevisionRepositoryImplUnderTest(JpaEntityInformation<T, ?> entityInformation,
|
||||
RevisionEntityInformation revisionEntityInformation, EntityManager entityManager) {
|
||||
super(entityInformation, revisionEntityInformation, entityManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Number> getRevisions(ID id, Class<T> type, AuditReader reader) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DummyEntity {
|
||||
}
|
||||
}
|
||||
@@ -183,4 +183,25 @@ public class RepositoryIntegrationTests {
|
||||
.extracting(c -> c.name, c -> c.code) //
|
||||
.containsExactly(null, null);
|
||||
}
|
||||
|
||||
@Test // #146
|
||||
public void shortCurcuitingWhenOffsetIsToLarge() {
|
||||
Country de = new Country();
|
||||
de.code = "de";
|
||||
de.name = "Deutschland";
|
||||
|
||||
countryRepository.save(de);
|
||||
|
||||
countryRepository.delete(de);
|
||||
|
||||
check(de, 0, 1);
|
||||
check(de, 1, 1);
|
||||
check(de, 2, 0);
|
||||
}
|
||||
|
||||
void check(Country de, int page, int expectedSize) {
|
||||
|
||||
Page<Revision<Integer, Country>> revisions = countryRepository.findRevisions(de.id, PageRequest.of(page,1));
|
||||
assertThat(revisions).hasSize(expectedSize);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user