DATAGEODE-367 - Expose EntityInformation and the GemfireTemplate on SimpleGemfireRepository.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 the original author or authors.
|
* Copyright 2012-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +19,7 @@ import org.springframework.data.domain.Sort;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GemFire specific extension of the Spring Data {@link CrudRepository} interface.
|
* Apache Geode extension of the Spring Data {@link CrudRepository} interface.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
@@ -28,10 +28,10 @@ import org.springframework.data.repository.CrudRepository;
|
|||||||
public interface GemfireRepository<T, ID> extends CrudRepository<T, ID> {
|
public interface GemfireRepository<T, ID> extends CrudRepository<T, ID> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all entities sorted by the given options.
|
* Returns all entities ordered by the given {@link Sort}.
|
||||||
*
|
*
|
||||||
* @param sort the Spring Data Commons Sort type defining the ordering criteria.
|
* @param sort {@link Sort} defining the ordering criteria.
|
||||||
* @return all entities sorted by the given options.
|
* @return all entities ordered by the given {@link Sort}.
|
||||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
||||||
* @see org.springframework.data.domain.Sort
|
* @see org.springframework.data.domain.Sort
|
||||||
* @see java.lang.Iterable
|
* @see java.lang.Iterable
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.gemfire.repository.support;
|
package org.springframework.data.gemfire.repository.support;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -37,22 +37,31 @@ import org.springframework.data.gemfire.repository.GemfireRepository;
|
|||||||
import org.springframework.data.gemfire.repository.Wrapper;
|
import org.springframework.data.gemfire.repository.Wrapper;
|
||||||
import org.springframework.data.gemfire.repository.query.QueryString;
|
import org.springframework.data.gemfire.repository.query.QueryString;
|
||||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||||
|
import org.springframework.data.gemfire.util.SpringUtils;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.core.EntityInformation;
|
import org.springframework.data.repository.core.EntityInformation;
|
||||||
import org.springframework.data.util.StreamUtils;
|
import org.springframework.data.util.StreamUtils;
|
||||||
import org.springframework.data.util.Streamable;
|
import org.springframework.data.util.Streamable;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Repository implementation for GemFire.
|
* Simple, basic {@link CrudRepository} implementation for Apache Geode.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author David Turanski
|
* @author David Turanski
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @see java.io.Serializable
|
* @see org.apache.geode.cache.Cache
|
||||||
|
* @see org.apache.geode.cache.CacheTransactionManager
|
||||||
|
* @see org.apache.geode.cache.Region
|
||||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||||
* @see org.springframework.data.gemfire.repository.GemfireRepository
|
* @see org.springframework.data.gemfire.repository.GemfireRepository
|
||||||
* @see org.apache.geode.cache.Cache
|
* @see org.springframework.data.repository.CrudRepository
|
||||||
* @see org.apache.geode.cache.Region
|
* @see org.springframework.data.repository.core.EntityInformation
|
||||||
*/
|
*/
|
||||||
public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID> {
|
public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID> {
|
||||||
|
|
||||||
@@ -60,18 +69,21 @@ public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID>
|
|||||||
|
|
||||||
private final GemfireTemplate template;
|
private final GemfireTemplate template;
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance of {@link SimpleGemfireRepository} initialized with the {@link GemfireTemplate}
|
* Constructs a new instance of {@link SimpleGemfireRepository} initialized with the {@link GemfireTemplate}
|
||||||
* and {@link EntityInformation}.
|
* and {@link EntityInformation}.
|
||||||
*
|
*
|
||||||
* @param template {@link GemfireTemplate} used to perform basic data access operations and simple OQL queries;
|
* @param template {@link GemfireTemplate} used to perform basic data access operations and simple OQL queries;
|
||||||
* must not be {@literal null}.
|
* must not be {@literal null}.
|
||||||
* @param entityInformation {@link EntityInformation} used to describe the entity; must not be {@literal null}.
|
* @param entityInformation {@link EntityInformation} that describes the entity; must not be {@literal null}.
|
||||||
* @throws IllegalArgumentException if {@link GemfireTemplate} or {@link EntityInformation} is {@literal null}.
|
* @throws IllegalArgumentException if {@link GemfireTemplate} or {@link EntityInformation} is {@literal null}.
|
||||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||||
* @see org.springframework.data.repository.core.EntityInformation
|
* @see org.springframework.data.repository.core.EntityInformation
|
||||||
*/
|
*/
|
||||||
public SimpleGemfireRepository(GemfireTemplate template, EntityInformation<T, ID> entityInformation) {
|
public SimpleGemfireRepository(@NonNull GemfireTemplate template,
|
||||||
|
@NonNull EntityInformation<T, ID> entityInformation) {
|
||||||
|
|
||||||
Assert.notNull(template, "GemfireTemplate must not be null");
|
Assert.notNull(template, "GemfireTemplate must not be null");
|
||||||
Assert.notNull(entityInformation, "EntityInformation must not be null");
|
Assert.notNull(entityInformation, "EntityInformation must not be null");
|
||||||
@@ -80,44 +92,110 @@ public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID>
|
|||||||
this.entityInformation = entityInformation;
|
this.entityInformation = entityInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the {@link EntityInformation} type describing the entity.
|
||||||
|
*
|
||||||
|
* @return a reference to the {@link EntityInformation} type describing the entity.
|
||||||
|
* @see org.springframework.data.repository.core.EntityInformation
|
||||||
|
*/
|
||||||
|
public @NonNull EntityInformation<T, ID> getEntityInformation() {
|
||||||
|
return this.entityInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the SLF4J {@link Logger} used to log the operations of this {@link GemfireRepository}.
|
||||||
|
*
|
||||||
|
* @return a reference to the SLF4J {@link Logger} used to log the operations of this {@link GemfireRepository}.
|
||||||
|
* @see org.slf4j.Logger
|
||||||
|
*/
|
||||||
|
public @NonNull Logger getLogger() {
|
||||||
|
return this.logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Region} to which this {@link GemfireRepository} performs all data access operations.
|
||||||
|
*
|
||||||
|
* @return a reference to the {@link Region} on which this {@link GemfireRepository} operates.
|
||||||
|
* @see org.apache.geode.cache.Region
|
||||||
|
* @see #getTemplate()
|
||||||
|
*/
|
||||||
|
public @NonNull Region<ID, T> getRegion() {
|
||||||
|
return getTemplate().getRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the {@link GemfireTemplate} used by this {@link GemfireRepository} to perform basic
|
||||||
|
* CRUD data access operations and simple OQL queries.
|
||||||
|
*
|
||||||
|
* @return a reference to the {@link GemfireTemplate} used by this {@link GemfireRepository}.
|
||||||
|
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||||
|
*/
|
||||||
|
public @NonNull GemfireTemplate getTemplate() {
|
||||||
|
return this.template;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <U extends T> U save(U entity) {
|
public <U extends T> U save(@NonNull U entity) {
|
||||||
|
|
||||||
ID id = this.entityInformation.getRequiredId(entity);
|
ID id = getEntityInformation().getRequiredId(entity);
|
||||||
|
|
||||||
this.template.put(id, entity);
|
// CREATE/UPDATE entity in Region
|
||||||
|
T existingValue = getTemplate().put(id, entity);
|
||||||
|
|
||||||
|
if (getLogger().isDebugEnabled()) {
|
||||||
|
getLogger().debug("Overwrote existing value [{}] for ID [{}]", existingValue, id);
|
||||||
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T save(Wrapper<T, ID> wrapper) {
|
public T save(@NonNull Wrapper<T, ID> wrapper) {
|
||||||
|
|
||||||
T entity = wrapper.getEntity();
|
T entity = wrapper.getEntity();
|
||||||
|
|
||||||
this.template.put(wrapper.getKey(), entity);
|
// CREATE/UPDATE entity in Region
|
||||||
|
T existingValue = getTemplate().put(wrapper.getKey(), entity);
|
||||||
|
|
||||||
|
if (getLogger().isDebugEnabled()) {
|
||||||
|
getLogger().debug("Overwrote existing value [{}] for ID [{}]", existingValue, wrapper.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <U extends T> Iterable<U> saveAll(Iterable<U> entities) {
|
public <U extends T> Iterable<U> saveAll(@NonNull Iterable<U> entities) {
|
||||||
|
|
||||||
|
EntityInformation<T, ID> entityInformation = getEntityInformation();
|
||||||
|
|
||||||
Map<ID, U> entitiesToSave = new HashMap<>();
|
Map<ID, U> entitiesToSave = new HashMap<>();
|
||||||
|
|
||||||
entities.forEach(entity -> entitiesToSave.put(this.entityInformation.getRequiredId(entity), entity));
|
Streamable.of(CollectionUtils.nullSafeIterable(entities)).stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(entity -> entitiesToSave.put(entityInformation.getRequiredId(entity), entity));
|
||||||
|
|
||||||
this.template.putAll(entitiesToSave);
|
if (!entitiesToSave.isEmpty()) {
|
||||||
|
getTemplate().putAll(entitiesToSave);
|
||||||
|
}
|
||||||
|
|
||||||
return entitiesToSave.values();
|
return entitiesToSave.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of entities stored in the {@link Region}.
|
||||||
|
*
|
||||||
|
* This method executes a {@literal SELECT count(*) FROM /Region} OQL query.
|
||||||
|
*
|
||||||
|
* @return a count of the number of entities stored in the {@link Region}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long count() {
|
public long count() {
|
||||||
|
|
||||||
String countQuery = String.format("SELECT count(*) FROM %s", this.template.getRegion().getFullPath());
|
String regionPath = getRegion().getFullPath();
|
||||||
|
String countQuery = String.format("SELECT count(*) FROM %s", regionPath);
|
||||||
|
|
||||||
SelectResults<Integer> results = this.template.find(countQuery);
|
SelectResults<Integer> results = getTemplate().find(countQuery);
|
||||||
|
|
||||||
return Optional.ofNullable(results)
|
return Optional.ofNullable(results)
|
||||||
.map(SelectResults::iterator)
|
.map(SelectResults::iterator)
|
||||||
@@ -127,64 +205,104 @@ public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID>
|
|||||||
.orElse(0L);
|
.orElse(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether an entity with the given ID is stored in the {@link Region}.
|
||||||
|
*
|
||||||
|
* @param id {@link Long} value identifying the entity.
|
||||||
|
* @return a boolean value indicating whether an entity with the given ID is stored in the {@link Region}.
|
||||||
|
* @see #findById(Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean existsById(ID id) {
|
public boolean existsById(ID id) {
|
||||||
return findById(id).isPresent();
|
return findById(id).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<T> findById(ID id) {
|
public @NonNull Iterable<T> findAll() {
|
||||||
return Optional.ofNullable(this.template.get(id));
|
|
||||||
|
String regionPath = getRegion().getFullPath();
|
||||||
|
String query = String.format("SELECT * FROM %s", regionPath);
|
||||||
|
|
||||||
|
SelectResults<T> selectResults = getTemplate().find(query);
|
||||||
|
|
||||||
|
return toList(selectResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<T> findAll() {
|
public @NonNull Iterable<T> findAll(@NonNull Sort sort) {
|
||||||
|
|
||||||
SelectResults<T> results =
|
|
||||||
this.template.find(String.format("SELECT * FROM %s", this.template.getRegion().getFullPath()));
|
|
||||||
|
|
||||||
return results.asList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<T> findAll(Sort sort) {
|
|
||||||
|
|
||||||
QueryString query = QueryString.of("SELECT * FROM /RegionPlaceholder")
|
QueryString query = QueryString.of("SELECT * FROM /RegionPlaceholder")
|
||||||
.fromRegion(this.entityInformation.getJavaType(), this.template.getRegion())
|
.fromRegion(getEntityInformation().getJavaType(), getRegion())
|
||||||
.orderBy(sort);
|
.orderBy(sort);
|
||||||
|
|
||||||
SelectResults<T> selectResults = this.template.find(query.toString());
|
SelectResults<T> selectResults = getTemplate().find(query.toString());
|
||||||
|
|
||||||
return selectResults.asList();
|
return toList(selectResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<T> findAllById(Iterable<ID> ids) {
|
public @NonNull Iterable<T> findAllById(@NonNull Iterable<ID> ids) {
|
||||||
|
|
||||||
List<ID> keys = Streamable.of(ids).stream().collect(StreamUtils.toUnmodifiableList());
|
List<ID> keys = Streamable.of(CollectionUtils.nullSafeIterable(ids)).stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(StreamUtils.toUnmodifiableList());
|
||||||
|
|
||||||
return CollectionUtils.<ID, T>nullSafeMap(this.template.getAll(keys)).values().stream()
|
Map<ID, T> keysValues = !keys.isEmpty()
|
||||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
? getTemplate().getAll(keys)
|
||||||
|
: Collections.emptyMap();
|
||||||
|
|
||||||
|
List<T> values = CollectionUtils.nullSafeMap(keysValues).values().stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(ID id) {
|
public Optional<T> findById(@NonNull ID id) {
|
||||||
this.template.remove(id);
|
|
||||||
|
T value = id != null
|
||||||
|
? getTemplate().get(id)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return Optional.ofNullable(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(T entity) {
|
public void delete(@NonNull T entity) {
|
||||||
deleteById(this.entityInformation.getRequiredId(entity));
|
deleteById(getEntityInformation().getRequiredId(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAll(Iterable<? extends T> entities) {
|
public void deleteAll() {
|
||||||
entities.forEach(this::delete);
|
|
||||||
|
getTemplate().execute((GemfireCallback<Void>) region -> {
|
||||||
|
|
||||||
|
if (isPartitioned(region) || isTransactionPresent(region)) {
|
||||||
|
doRegionClear(region);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SpringUtils.safeDoOperation(() -> region.clear(), () -> doRegionClear(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAll(@NonNull Iterable<? extends T> entities) {
|
||||||
|
CollectionUtils.nullSafeIterable(entities).forEach(this::delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteById(@NonNull ID id) {
|
||||||
|
getTemplate().remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isPartitioned(Region<?, ?> region) {
|
boolean isPartitioned(Region<?, ?> region) {
|
||||||
|
|
||||||
return region != null && region.getAttributes() != null
|
return region != null
|
||||||
|
&& region.getAttributes() != null
|
||||||
&& isPartitioned(region.getAttributes().getDataPolicy());
|
&& isPartitioned(region.getAttributes().getDataPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,23 +324,10 @@ public class SimpleGemfireRepository<T, ID> implements GemfireRepository<T, ID>
|
|||||||
region.removeAll(region.keySet());
|
region.removeAll(region.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NonNull List<T> toList(@Nullable SelectResults<T> selectResults) {
|
||||||
public void deleteAll() {
|
|
||||||
this.template.execute((GemfireCallback<Void>) region -> {
|
|
||||||
|
|
||||||
if (isPartitioned(region) || isTransactionPresent(region)) {
|
return selectResults != null
|
||||||
doRegionClear(region);
|
? CollectionUtils.nullSafeList(selectResults.asList())
|
||||||
}
|
: Collections.emptyList();
|
||||||
else {
|
|
||||||
try {
|
|
||||||
region.clear();
|
|
||||||
}
|
|
||||||
catch (UnsupportedOperationException ignore) {
|
|
||||||
doRegionClear(region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 the original author or authors.
|
* Copyright 2010-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.gemfire.repository.sample;
|
package org.springframework.data.gemfire.repository.sample;
|
||||||
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
@@ -23,7 +22,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
* @author Stuart Williams
|
* @author Stuart Williams
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
*/
|
*/
|
||||||
public class Animal {
|
public class Animal implements Identifiable<Long> {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
@@ -31,7 +30,7 @@ public class Animal {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Long id) {
|
public void setId(Long id) {
|
||||||
@@ -39,7 +38,7 @@ public class Animal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
@@ -48,7 +47,8 @@ public class Animal {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
if (obj == this) {
|
|
||||||
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,15 +64,18 @@ public class Animal {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
|
||||||
int hashValue = 17;
|
int hashValue = 17;
|
||||||
|
|
||||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId());
|
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId());
|
||||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getName());
|
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getName());
|
||||||
|
|
||||||
return hashValue;
|
return hashValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("{ @type = %1$s, id = %2$d, name = %3$s }", getClass().getSimpleName(), getId(), getName());
|
return String.format("{ @type = %1$s, id = %2$d, name = %3$s }",
|
||||||
|
getClass().getSimpleName(), getId(), getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
*
|
||||||
|
* https://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.gemfire.repository.sample;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a contract for Abstract Data Types (ADT) that can be identified.
|
||||||
|
*
|
||||||
|
* @author John Blum
|
||||||
|
* @since 2.4.0
|
||||||
|
*/
|
||||||
|
public interface Identifiable<T> {
|
||||||
|
|
||||||
|
T getId();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 the original author or authors.
|
* Copyright 2012-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,27 +13,25 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.gemfire.repository.support;
|
package org.springframework.data.gemfire.repository.support;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.apache.geode.cache.GemFireCache;
|
import org.apache.geode.cache.GemFireCache;
|
||||||
import org.apache.geode.cache.Region;
|
import org.apache.geode.cache.Region;
|
||||||
import org.apache.geode.cache.RegionEvent;
|
import org.apache.geode.cache.RegionEvent;
|
||||||
import org.apache.geode.cache.query.SelectResults;
|
import org.apache.geode.cache.query.SelectResults;
|
||||||
import org.apache.geode.cache.util.CacheListenerAdapter;
|
import org.apache.geode.cache.util.CacheListenerAdapter;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.data.gemfire.GemfireTemplate;
|
import org.springframework.data.gemfire.GemfireTemplate;
|
||||||
@@ -48,11 +46,16 @@ import org.springframework.test.context.ContextConfiguration;
|
|||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link SimpleGemfireRepository}.
|
* Integration Tests for {@link SimpleGemfireRepository}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author John Blum
|
* @author John Blum
|
||||||
* @see org.junit.Test
|
* @see org.junit.Test
|
||||||
|
* @see org.apache.geode.cache.GemFireCache
|
||||||
|
* @see org.apache.geode.cache.Region
|
||||||
|
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||||
|
* @see org.springframework.data.gemfire.LocalRegionFactoryBean
|
||||||
|
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
|
||||||
* @see org.springframework.data.gemfire.repository.support.SimpleGemfireRepository
|
* @see org.springframework.data.gemfire.repository.support.SimpleGemfireRepository
|
||||||
* @see org.springframework.test.context.ContextConfiguration
|
* @see org.springframework.test.context.ContextConfiguration
|
||||||
* @see org.springframework.test.context.junit4.SpringRunner
|
* @see org.springframework.test.context.junit4.SpringRunner
|
||||||
@@ -113,17 +116,17 @@ public class SimpleGemfireRepositoryIntegrationTests {
|
|||||||
this.template.put(carter.getId(), carter);
|
this.template.put(carter.getId(), carter);
|
||||||
this.template.put(leroi.getId(), leroi);
|
this.template.put(leroi.getId(), leroi);
|
||||||
|
|
||||||
Collection<Person> result = this.repository.findAllById(Arrays.asList(carter.getId(), leroi.getId()));
|
Iterable<Person> result = this.repository.findAllById(Arrays.asList(carter.getId(), leroi.getId()));
|
||||||
|
|
||||||
assertThat(result).isNotNull();
|
assertThat(result).isNotNull();
|
||||||
assertThat(result.size()).isEqualTo(2);
|
assertThat(result).hasSize(2);
|
||||||
assertThat(result).containsAll(Arrays.asList(carter, leroi));
|
assertThat(result).containsAll(Arrays.asList(carter, leroi));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllWithIdsReturnsNoMatches() {
|
public void findAllWithIdsReturnsNoMatches() {
|
||||||
|
|
||||||
Collection<Person> results = this.repository.findAllById(Arrays.asList(1L, 2L));
|
Iterable<Person> results = this.repository.findAllById(Arrays.asList(1L, 2L));
|
||||||
|
|
||||||
assertThat(results).isNotNull();
|
assertThat(results).isNotNull();
|
||||||
assertThat(results).isEmpty();
|
assertThat(results).isEmpty();
|
||||||
@@ -139,7 +142,7 @@ public class SimpleGemfireRepositoryIntegrationTests {
|
|||||||
this.template.put(kurt.getId(), kurt);
|
this.template.put(kurt.getId(), kurt);
|
||||||
this.template.put(eddie.getId(), eddie);
|
this.template.put(eddie.getId(), eddie);
|
||||||
|
|
||||||
Collection<Person> results = this.repository.findAllById(Arrays.asList(0L, 1L, 2L, 4L));
|
Iterable<Person> results = this.repository.findAllById(Arrays.asList(0L, 1L, 2L, 4L));
|
||||||
|
|
||||||
assertThat(results).isNotNull();
|
assertThat(results).isNotNull();
|
||||||
assertThat(results).hasSize(2);
|
assertThat(results).hasSize(2);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ package org.springframework.data.gemfire.repository.support;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
@@ -35,6 +37,7 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -54,11 +57,15 @@ import org.apache.geode.cache.Region;
|
|||||||
import org.apache.geode.cache.RegionAttributes;
|
import org.apache.geode.cache.RegionAttributes;
|
||||||
import org.apache.geode.cache.query.SelectResults;
|
import org.apache.geode.cache.query.SelectResults;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.gemfire.GemfireTemplate;
|
import org.springframework.data.gemfire.GemfireTemplate;
|
||||||
import org.springframework.data.gemfire.repository.Wrapper;
|
import org.springframework.data.gemfire.repository.Wrapper;
|
||||||
import org.springframework.data.gemfire.repository.sample.Animal;
|
import org.springframework.data.gemfire.repository.sample.Animal;
|
||||||
|
import org.springframework.data.gemfire.repository.sample.Identifiable;
|
||||||
import org.springframework.data.repository.core.EntityInformation;
|
import org.springframework.data.repository.core.EntityInformation;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit Tests for {@link SimpleGemfireRepository}.
|
* Unit Tests for {@link SimpleGemfireRepository}.
|
||||||
*
|
*
|
||||||
@@ -75,10 +82,12 @@ import org.springframework.data.repository.core.EntityInformation;
|
|||||||
* @see org.springframework.data.repository.core.EntityInformation
|
* @see org.springframework.data.repository.core.EntityInformation
|
||||||
* @since 1.4.5
|
* @since 1.4.5
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
public class SimpleGemfireRepositoryUnitTests {
|
public class SimpleGemfireRepositoryUnitTests {
|
||||||
|
|
||||||
protected Map<Long, Animal> asMap(Iterable<Animal> animals) {
|
private final AtomicLong idSequence = new AtomicLong(0L);
|
||||||
|
|
||||||
|
private Map<Long, Animal> asMap(Iterable<Animal> animals) {
|
||||||
|
|
||||||
Map<Long, Animal> animalMap = new HashMap<>();
|
Map<Long, Animal> animalMap = new HashMap<>();
|
||||||
|
|
||||||
@@ -89,16 +98,17 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
return animalMap;
|
return animalMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Animal newAnimal(String name) {
|
private Animal newAnimal(String name) {
|
||||||
|
|
||||||
Animal animal = new Animal();
|
Animal animal = new Animal();
|
||||||
|
|
||||||
|
animal.setId(this.idSequence.incrementAndGet());
|
||||||
animal.setName(name);
|
animal.setName(name);
|
||||||
|
|
||||||
return animal;
|
return animal;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Animal newAnimal(Long id, String name) {
|
private Animal newAnimal(Long id, String name) {
|
||||||
|
|
||||||
Animal animal = newAnimal(name);
|
Animal animal = newAnimal(name);
|
||||||
|
|
||||||
@@ -107,11 +117,15 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
return animal;
|
return animal;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GemfireTemplate newGemfireTemplate(Region<?, ?> region) {
|
private GemfireTemplate newGemfireTemplate(Region<?, ?> region) {
|
||||||
return new GemfireTemplate(region);
|
return new GemfireTemplate(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cache mockCache(String name, boolean transactionExists) {
|
private <ID, T extends Identifiable<ID>> Wrapper<T, ID> newWrapper(T entity) {
|
||||||
|
return new Wrapper<>(entity, entity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cache mockCache(String name, boolean transactionExists) {
|
||||||
|
|
||||||
Cache mockCache = mock(Cache.class, String.format("%s.MockCache", name));
|
Cache mockCache = mock(Cache.class, String.format("%s.MockCache", name));
|
||||||
|
|
||||||
@@ -124,7 +138,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
return mockCache;
|
return mockCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EntityInformation<Animal, Long> mockEntityInformation() {
|
private EntityInformation<Animal, Long> mockEntityInformation() {
|
||||||
|
|
||||||
EntityInformation<Animal, Long> mockEntityInformation = mock(EntityInformation.class);
|
EntityInformation<Animal, Long> mockEntityInformation = mock(EntityInformation.class);
|
||||||
|
|
||||||
@@ -149,11 +163,11 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
return mockEntityInformation;
|
return mockEntityInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Region mockRegion() {
|
private Region mockRegion() {
|
||||||
return mockRegion("MockRegion");
|
return mockRegion("MockRegion");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Region mockRegion(String name) {
|
private Region mockRegion(String name) {
|
||||||
|
|
||||||
Region mockRegion = mock(Region.class, String.format("%s.MockRegion", name));
|
Region mockRegion = mock(Region.class, String.format("%s.MockRegion", name));
|
||||||
|
|
||||||
@@ -163,7 +177,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
return mockRegion;
|
return mockRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Region mockRegion(String name, Cache mockCache, DataPolicy dataPolicy) {
|
private Region mockRegion(String name, Cache mockCache, DataPolicy dataPolicy) {
|
||||||
|
|
||||||
Region mockRegion = mockRegion(name);
|
Region mockRegion = mockRegion(name);
|
||||||
|
|
||||||
@@ -179,17 +193,20 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructsSimpleGemfireRepositorySuccessfully() {
|
public void constructSimpleGemfireRepositorySuccessfully() {
|
||||||
|
|
||||||
Region mockRegion = mock(Region.class);
|
Region mockRegion = mockRegion();
|
||||||
|
|
||||||
GemfireTemplate template = spy(new GemfireTemplate(mockRegion));
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
EntityInformation mockEntityInformation = mock(EntityInformation.class);
|
EntityInformation mockEntityInformation = mockEntityInformation();
|
||||||
|
|
||||||
SimpleGemfireRepository repository = new SimpleGemfireRepository(template, mockEntityInformation);
|
SimpleGemfireRepository repository = new SimpleGemfireRepository(template, mockEntityInformation);
|
||||||
|
|
||||||
assertThat(repository).isNotNull();
|
assertThat(repository).isNotNull();
|
||||||
|
assertThat(repository.getEntityInformation()).isEqualTo(mockEntityInformation);
|
||||||
|
assertThat(repository.getLogger()).isNotNull();
|
||||||
|
assertThat(repository.getTemplate()).isEqualTo(template);
|
||||||
|
|
||||||
verifyNoInteractions(template, mockRegion, mockEntityInformation);
|
verifyNoInteractions(template, mockRegion, mockEntityInformation);
|
||||||
}
|
}
|
||||||
@@ -225,29 +242,63 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saveEntityIsCorrect() {
|
public void getRegionFromTemplate() {
|
||||||
|
|
||||||
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
|
EntityInformation<Animal, Long> mockEntityInformation = mockEntityInformation();
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
new SimpleGemfireRepository<>(template, mockEntityInformation);
|
||||||
|
|
||||||
|
assertThat(repository).isNotNull();
|
||||||
|
assertThat(repository.getTemplate()).isEqualTo(template);
|
||||||
|
assertThat(repository.getRegion()).isEqualTo(mockRegion);
|
||||||
|
|
||||||
|
verify(template, times(1)).getRegion();
|
||||||
|
verifyNoInteractions(mockRegion, mockEntityInformation);
|
||||||
|
verifyNoMoreInteractions(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveEntitySuccessfully() {
|
||||||
|
|
||||||
|
Animal cat = newAnimal(1L, "cat");
|
||||||
|
|
||||||
|
Logger mockLogger = mock(Logger.class);
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
spy(new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation()));
|
||||||
|
|
||||||
Animal dog = repository.save(newAnimal("dog"));
|
doReturn(mockLogger).when(repository).getLogger();
|
||||||
|
doReturn(true).when(mockLogger).isDebugEnabled();
|
||||||
|
doReturn(cat).when(mockRegion).put(anyLong(), any());
|
||||||
|
|
||||||
|
Animal dog = repository.save(newAnimal(1L, "dog"));
|
||||||
|
|
||||||
assertThat(dog).isNotNull();
|
assertThat(dog).isNotNull();
|
||||||
assertThat(dog.getId().longValue()).isEqualTo(1L);
|
assertThat(dog.getId().longValue()).isEqualTo(1L);
|
||||||
assertThat(dog.getName()).isEqualTo("dog");
|
assertThat(dog.getName()).isEqualTo("dog");
|
||||||
|
|
||||||
|
verify(mockLogger, times(1)).isDebugEnabled();
|
||||||
|
verify(mockLogger, times(1))
|
||||||
|
.debug(eq("Overwrote existing value [{}] for ID [{}]"), eq(cat), eq(1L));
|
||||||
verify(mockRegion, times(1)).put(eq(1L), eq(dog));
|
verify(mockRegion, times(1)).put(eq(1L), eq(dog));
|
||||||
|
verifyNoMoreInteractions(mockLogger, mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saveEntitiesIsCorrect() {
|
public void saveEntitiesSuccessfully() {
|
||||||
|
|
||||||
List<Animal> animals = new ArrayList<>(3);
|
List<Animal> animals = new ArrayList<>(3);
|
||||||
|
|
||||||
animals.add(newAnimal("bird"));
|
animals.add(newAnimal(1L, "bird"));
|
||||||
animals.add(newAnimal("cat"));
|
animals.add(newAnimal(2L, "cat"));
|
||||||
animals.add(newAnimal("dog"));
|
animals.add(newAnimal(3L, "dog"));
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
@@ -257,24 +308,82 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
Iterable<Animal> savedAnimals = repository.saveAll(animals);
|
Iterable<Animal> savedAnimals = repository.saveAll(animals);
|
||||||
|
|
||||||
assertThat(savedAnimals).isNotNull();
|
assertThat(savedAnimals).isNotNull();
|
||||||
|
assertThat(savedAnimals).isNotSameAs(animals);
|
||||||
|
assertThat(savedAnimals).containsAll(animals);
|
||||||
|
|
||||||
verify(mockRegion, times(1)).putAll(eq(asMap(savedAnimals)));
|
verify(mockRegion, times(1)).putAll(eq(asMap(savedAnimals)));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saveWrapperIsCorrect() {
|
public void saveWrapperSuccessfully() {
|
||||||
Animal dog = newAnimal(1L, "dog");
|
|
||||||
|
|
||||||
Wrapper dogWrapper = new Wrapper(dog, dog.getId());
|
Animal dog = newAnimal(2L, "dog");
|
||||||
|
|
||||||
|
Logger mockLogger = mock(Logger.class);
|
||||||
|
|
||||||
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
spy(new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation()));
|
||||||
|
|
||||||
|
doReturn(mockLogger).when(repository).getLogger();
|
||||||
|
doReturn(true).when(mockLogger).isDebugEnabled();
|
||||||
|
doReturn(dog).when(mockRegion).put(anyLong(), any());
|
||||||
|
|
||||||
|
Animal cat = repository.save(newWrapper(newAnimal(2L, "cat")));
|
||||||
|
|
||||||
|
assertThat(cat).isNotNull();
|
||||||
|
assertThat(cat.getId()).isEqualTo(2L);
|
||||||
|
assertThat(cat.getName()).isEqualTo("cat");
|
||||||
|
|
||||||
|
verify(mockLogger, times(1)).isDebugEnabled();
|
||||||
|
verify(mockLogger, times(1))
|
||||||
|
.debug(eq("Overwrote existing value [{}] for ID [{}]"), eq(dog), eq(2L));
|
||||||
|
verify(mockRegion, times(1)).put(eq(2L), eq(cat));
|
||||||
|
verifyNoMoreInteractions(mockLogger, mockRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveAllEntitiesWithIterableContainingNullEntitiesIsNullSafe() {
|
||||||
|
|
||||||
|
List<Animal> animals = new ArrayList<>();
|
||||||
|
|
||||||
|
animals.add(newAnimal(1L, "cat"));
|
||||||
|
animals.add(null);
|
||||||
|
animals.add(newAnimal(2L, "dog"));
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
assertThat(repository.save(dogWrapper)).isEqualTo(dog);
|
Iterable<Animal> savedAnimals = repository.saveAll(animals);
|
||||||
|
|
||||||
verify(mockRegion, times(1)).put(eq(dog.getId()), eq(dog));
|
assertThat(savedAnimals).isNotNull();
|
||||||
|
assertThat(savedAnimals).isNotSameAs(animals);
|
||||||
|
assertThat(savedAnimals).hasSize(2);
|
||||||
|
assertThat(savedAnimals).containsAll(Arrays.asList(animals.get(0), animals.get(2)));
|
||||||
|
|
||||||
|
verify(mockRegion, times(1))
|
||||||
|
.putAll(eq(asMap(Arrays.asList(animals.get(0), animals.get(2)))));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveAllEntitiesWithNullIterableIsNullSafe() {
|
||||||
|
|
||||||
|
Region<Long, Animal> mockRegion = mock(Region.class);
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
|
Iterable<?> iterable = repository.saveAll(null);
|
||||||
|
|
||||||
|
assertThat(iterable).isNotNull();
|
||||||
|
assertThat(iterable).isEmpty();
|
||||||
|
|
||||||
|
verifyNoInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -287,7 +396,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
doReturn(mockSelectResults).when(template).find(eq("SELECT count(*) FROM /Example"));
|
doReturn(mockSelectResults).when(template).find(eq("SELECT count(*) FROM /Example"));
|
||||||
when(mockSelectResults.iterator()).thenReturn(Collections.singletonList(21).iterator());
|
doReturn(Collections.singletonList(21).iterator()).when(mockSelectResults).iterator();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(template, mockEntityInformation());
|
new SimpleGemfireRepository<>(template, mockEntityInformation());
|
||||||
@@ -309,7 +418,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
doReturn(null).when(template).find(eq("SELECT count(*) FROM /Example"));
|
doReturn(null).when(template).find(anyString());
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(template, mockEntityInformation());
|
new SimpleGemfireRepository<>(template, mockEntityInformation());
|
||||||
@@ -332,7 +441,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
doReturn(mockSelectResults).when(template).find(eq("SELECT count(*) FROM /Example"));
|
doReturn(mockSelectResults).when(template).find(anyString());
|
||||||
doReturn(null).when(mockSelectResults).iterator();
|
doReturn(null).when(mockSelectResults).iterator();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
@@ -357,7 +466,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
doReturn(mockSelectResults).when(template).find(eq("SELECT count(*) FROM /Example"));
|
doReturn(mockSelectResults).when(template).find(anyString());
|
||||||
doReturn(Collections.emptyIterator()).when(mockSelectResults).iterator();
|
doReturn(Collections.emptyIterator()).when(mockSelectResults).iterator();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
@@ -374,123 +483,263 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void existsIsCorrect() {
|
public void countWhenSelectResultsIteratorContainsNullIsNullSafeReturnsZero() {
|
||||||
|
|
||||||
|
SelectResults mockSelectResults = mock(SelectResults.class);
|
||||||
|
|
||||||
|
Region mockRegion = mockRegion("Example");
|
||||||
|
|
||||||
|
Iterator mockIterator = mock(Iterator.class);
|
||||||
|
|
||||||
|
GemfireTemplate template = spy(newGemfireTemplate(mockRegion));
|
||||||
|
|
||||||
|
doReturn(mockSelectResults).when(template).find(anyString());
|
||||||
|
doReturn(mockIterator).when(mockSelectResults).iterator();
|
||||||
|
doReturn(true).when(mockIterator).hasNext();
|
||||||
|
doReturn(null).when(mockIterator).next();
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
new SimpleGemfireRepository<>(template, mockEntityInformation());
|
||||||
|
|
||||||
|
assertThat(repository).isNotNull();
|
||||||
|
assertThat(repository.count()).isEqualTo(0L);
|
||||||
|
|
||||||
|
verify(template, times(1)).getRegion();
|
||||||
|
verify(mockRegion, times(1)).getFullPath();
|
||||||
|
verify(template, times(1)).find(eq("SELECT count(*) FROM /Example"));
|
||||||
|
verify(mockSelectResults, times(1)).iterator();
|
||||||
|
verify(mockIterator, times(1)).hasNext();
|
||||||
|
verify(mockIterator, times(1)).next();
|
||||||
|
verifyNoMoreInteractions(mockIterator, mockRegion, mockSelectResults, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void existsByIdCallsFindById() {
|
||||||
|
|
||||||
Animal dog = newAnimal(1L, "dog");
|
Animal dog = newAnimal(1L, "dog");
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
when(mockRegion.get(any(Long.class))).then(
|
doAnswer(invocation -> dog.getId().equals(invocation.getArgument(0)) ? dog : null)
|
||||||
invocation -> (dog.getId().equals(invocation.getArguments()[0]) ? dog : null));
|
.when(mockRegion).get(anyLong());
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
spy(new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation()));
|
||||||
|
|
||||||
assertThat(repository.existsById(1L)).isTrue();
|
assertThat(repository.existsById(1L)).isTrue();
|
||||||
|
assertThat(repository.existsById(2L)).isFalse();
|
||||||
assertThat(repository.existsById(10L)).isFalse();
|
assertThat(repository.existsById(10L)).isFalse();
|
||||||
|
|
||||||
|
verify(repository, times(1)).findById(eq(1L));
|
||||||
|
verify(mockRegion, times(1)).get(eq(1L));
|
||||||
|
verify(repository, times(1)).findById(eq(2L));
|
||||||
|
verify(mockRegion, times(1)).get(eq(2L));
|
||||||
|
verify(repository, times(1)).findById(eq(10L));
|
||||||
|
verify(mockRegion, times(1)).get(eq(10L));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOneIsCorrect() {
|
public void findAllSuccessfully() {
|
||||||
Animal dog = newAnimal(1L, "dog");
|
|
||||||
|
GemfireTemplate mockTemplate = mock(GemfireTemplate.class);
|
||||||
|
|
||||||
|
List<Object> results = Arrays.asList("test", "mock", "fake");
|
||||||
|
|
||||||
|
Region mockRegion = mockRegion("Example");
|
||||||
|
|
||||||
|
SelectResults mockSelectResults = mock(SelectResults.class);
|
||||||
|
|
||||||
|
doReturn(mockRegion).when(mockTemplate).getRegion();
|
||||||
|
doReturn(mockSelectResults).when(mockTemplate).find(anyString());
|
||||||
|
doReturn(results).when(mockSelectResults).asList();
|
||||||
|
|
||||||
|
SimpleGemfireRepository repository = new SimpleGemfireRepository(mockTemplate, mockEntityInformation());
|
||||||
|
|
||||||
|
Iterable<Object> returnValue = repository.findAll();
|
||||||
|
|
||||||
|
assertThat(returnValue).isNotNull();
|
||||||
|
assertThat(returnValue).containsAll(results);
|
||||||
|
|
||||||
|
verify(mockTemplate, times(1)).getRegion();
|
||||||
|
verify(mockRegion, times(1)).getFullPath();
|
||||||
|
verify(mockTemplate, times(1)).find(eq("SELECT * FROM /Example"));
|
||||||
|
verify(mockSelectResults, times(1)).asList();
|
||||||
|
verifyNoMoreInteractions(mockRegion, mockSelectResults, mockTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllOrderedBySortSuccessfully() {
|
||||||
|
|
||||||
|
GemfireTemplate mockTemplate = mock(GemfireTemplate.class);
|
||||||
|
|
||||||
|
List<Object> results = Arrays.asList("test", "mock", "fake");
|
||||||
|
|
||||||
|
Region mockRegion = mockRegion("Example");
|
||||||
|
|
||||||
|
SelectResults mockSelectResults = mock(SelectResults.class);
|
||||||
|
|
||||||
|
doReturn(mockRegion).when(mockTemplate).getRegion();
|
||||||
|
doReturn(mockSelectResults).when(mockTemplate).find(anyString());
|
||||||
|
doReturn(results).when(mockSelectResults).asList();
|
||||||
|
|
||||||
|
SimpleGemfireRepository repository = new SimpleGemfireRepository(mockTemplate, mockEntityInformation());
|
||||||
|
|
||||||
|
Iterable<Object> returnValue = repository.findAll(Sort.by(Sort.Order.asc("name"), Sort.Order.desc("birthDate")));
|
||||||
|
|
||||||
|
assertThat(returnValue).isNotNull();
|
||||||
|
assertThat(returnValue).containsAll(results);
|
||||||
|
|
||||||
|
verify(mockTemplate, times(1)).getRegion();
|
||||||
|
verify(mockRegion, times(1)).getFullPath();
|
||||||
|
verify(mockTemplate, times(1))
|
||||||
|
.find(eq("SELECT DISTINCT * FROM /Example ORDER BY name ASC, birthDate DESC"));
|
||||||
|
verify(mockSelectResults, times(1)).asList();
|
||||||
|
verifyNoMoreInteractions(mockRegion, mockSelectResults, mockTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllByIdSuccessfully() {
|
||||||
|
|
||||||
|
Map<Long, Animal> animals = Stream.of(
|
||||||
|
newAnimal(1L, "bird"),
|
||||||
|
newAnimal(2L, "cat"),
|
||||||
|
newAnimal(3L, "dog")
|
||||||
|
).collect(Collectors.toMap(Animal::getId, Function.identity()));
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
when(mockRegion.get(any(Long.class))).then(
|
doAnswer(invocation -> {
|
||||||
invocation -> (dog.getId().equals(invocation.getArguments()[0]) ? dog : null));
|
|
||||||
|
Collection<Long> keys = invocation.getArgument(0);
|
||||||
|
|
||||||
|
return animals.values().stream()
|
||||||
|
.filter((animal -> keys.contains(animal.getId())))
|
||||||
|
.collect(Collectors.toMap(Animal::getId, Function.identity()));
|
||||||
|
|
||||||
|
}).when(mockRegion).getAll(any(Collection.class));
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
assertThat(repository.findById(1L).orElse(null)).isEqualTo(dog);
|
Iterable<Animal> animalsFound = repository.findAllById(Arrays.asList(1L, 3L));
|
||||||
assertThat(repository.findById(10L).isPresent()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void findAllIsCorrect() {
|
|
||||||
Map<Long, Animal> animals =
|
|
||||||
Stream.of(newAnimal(1L, "bird"), newAnimal(2L, "cat"), newAnimal(3L, "dog"))
|
|
||||||
.collect(Collectors.toMap(Animal::getId, Function.identity()));
|
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
|
||||||
|
|
||||||
when(mockRegion.getAll(any(Collection.class))).then(invocation -> {
|
|
||||||
Collection<Long> keys = invocation.getArgument(0);
|
|
||||||
|
|
||||||
return animals.values().stream().filter((animal -> keys.contains(animal.getId())))
|
|
||||||
.collect(Collectors.toMap(Animal::getId, Function.identity()));
|
|
||||||
});
|
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository = new SimpleGemfireRepository<>(
|
|
||||||
newGemfireTemplate(mockRegion), mockEntityInformation());
|
|
||||||
|
|
||||||
Collection<Animal> animalsFound = repository.findAllById(Arrays.asList(1L, 3L));
|
|
||||||
|
|
||||||
assertThat(animalsFound).isNotNull();
|
assertThat(animalsFound).isNotNull();
|
||||||
assertThat(animalsFound).hasSize(2);
|
assertThat(animalsFound).hasSize(2);
|
||||||
assertThat(animalsFound).contains(animals.get(1L), animals.get(3L));
|
assertThat(animalsFound).contains(animals.get(1L), animals.get(3L));
|
||||||
|
|
||||||
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(1L, 3L)));
|
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(1L, 3L)));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllWithIdsReturnsNoMatches() {
|
public void findAllByIdReturnsNoMatches() {
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
when(mockRegion.getAll(any(Collection.class))).then(invocation -> {
|
doReturn(Collections.emptyMap()).when(mockRegion).getAll(any(Collection.class));
|
||||||
Collection<Long> keys = invocation.getArgument(0);
|
|
||||||
Map<Long, Animal> result = new HashMap<>(keys.size());
|
|
||||||
|
|
||||||
for (Long key : keys) {
|
|
||||||
result.put(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
Collection<Animal> animalsFound = repository.findAllById(Arrays.asList(1L, 2L, 3L));
|
Iterable<Animal> animalsFound = repository.findAllById(Arrays.asList(1L, null, 2L, null, 3L));
|
||||||
|
|
||||||
assertThat(animalsFound).isNotNull();
|
assertThat(animalsFound).isNotNull();
|
||||||
assertThat(animalsFound).isEmpty();
|
assertThat(animalsFound).isEmpty();
|
||||||
|
|
||||||
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(1L, 2L, 3L)));
|
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(1L, 2L, 3L)));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllWithIdsReturnsPartialMatches() {
|
public void findAllByIdReturnsPartialMatches() {
|
||||||
Map<Long, Animal> animals =
|
|
||||||
Stream.of(newAnimal(1L, "bird"), newAnimal(2L, "cat"), newAnimal(3L, "dog"))
|
Map<Long, Animal> animals = Stream.of(
|
||||||
.collect(Collectors.toMap(Animal::getId, Function.identity()));
|
newAnimal(1L, "bird"),
|
||||||
|
newAnimal(2L, "cat"),
|
||||||
|
newAnimal(3L, "dog")
|
||||||
|
).collect(Collectors.toMap(Animal::getId, Function.identity()));
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
when(mockRegion.getAll(any(Collection.class))).then(invocation -> {
|
doAnswer(invocation -> {
|
||||||
|
|
||||||
Collection<Long> keys = invocation.getArgument(0);
|
Collection<Long> keys = invocation.getArgument(0);
|
||||||
Map<Long, Animal> result = new HashMap<>(keys.size());
|
|
||||||
|
|
||||||
for (Long key : keys) {
|
return keys.stream()
|
||||||
result.put(key, animals.get(key));
|
.filter(animals::containsKey)
|
||||||
}
|
.collect(Collectors.toMap(Function.identity(), animals::get));
|
||||||
|
|
||||||
return result;
|
}).when(mockRegion).getAll(any(Collection.class));
|
||||||
});
|
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
Collection<Animal> animalsFound = repository.findAllById(Arrays.asList(0L, 1L, 2L, 4L));
|
Iterable<Animal> animalsFound = repository.findAllById(Arrays.asList(null, 0L, null, 1L, 2L, 4L, null));
|
||||||
|
|
||||||
assertThat(animalsFound).isNotNull();
|
assertThat(animalsFound).isNotNull();
|
||||||
assertThat(animalsFound).hasSize(2);
|
assertThat(animalsFound).hasSize(2);
|
||||||
assertThat(animalsFound).contains(animals.get(1L), animals.get(2L));
|
assertThat(animalsFound).contains(animals.get(1L), animals.get(2L));
|
||||||
|
|
||||||
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(0L, 1L, 2L, 4L)));
|
verify(mockRegion, times(1)).getAll(eq(Arrays.asList(0L, 1L, 2L, 4L)));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteByIdIsCorrect() {
|
public void findAllByIdWithNullIterableIsNullSafe() {
|
||||||
|
|
||||||
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
new SimpleGemfireRepository(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
|
Iterable<Animal> animals = repository.findAllById(null);
|
||||||
|
|
||||||
|
assertThat(animals).isNotNull();
|
||||||
|
assertThat(animals).isEmpty();
|
||||||
|
|
||||||
|
verifyNoInteractions(mockRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByIdSuccessfully() {
|
||||||
|
|
||||||
|
Animal dog = newAnimal(1L, "dog");
|
||||||
|
|
||||||
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
|
doAnswer(invocation -> dog.getId().equals(invocation.getArgument(0)) ? dog : null)
|
||||||
|
.when(mockRegion).get(any(Long.class));
|
||||||
|
|
||||||
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
|
assertThat(repository.findById(1L).orElse(null)).isEqualTo(dog);
|
||||||
|
assertThat(repository.findById(2L).isPresent()).isFalse();
|
||||||
|
assertThat(repository.findById(10L).isPresent()).isFalse();
|
||||||
|
|
||||||
|
verify(mockRegion, times(1)).get(eq(1L));
|
||||||
|
verify(mockRegion, times(1)).get(eq(2L));
|
||||||
|
verify(mockRegion, times(1)).get(eq(10L));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByIdWithNullIdIsNullSafe() {
|
||||||
|
|
||||||
|
Region mockRegion = mockRegion();
|
||||||
|
|
||||||
|
SimpleGemfireRepository repository =
|
||||||
|
new SimpleGemfireRepository(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
|
assertThat(repository.findById(null).isPresent()).isFalse();
|
||||||
|
|
||||||
|
verifyNoInteractions(mockRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteByIdSuccessfully() {
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
@@ -499,37 +748,47 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
repository.deleteById(1L);
|
repository.deleteById(1L);
|
||||||
|
|
||||||
verify(mockRegion, times(1)).remove(eq(1L));
|
verify(mockRegion, times(1)).remove(eq(1L));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteEntityIsCorrect() {
|
public void deleteEntitySuccessfully() {
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
spy(new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation()));
|
||||||
|
|
||||||
repository.delete(newAnimal(1L, "dog"));
|
repository.delete(newAnimal(1L, "dog"));
|
||||||
|
|
||||||
|
verify(repository, times(1)).deleteById(eq(1L));
|
||||||
verify(mockRegion, times(1)).remove(eq(1L));
|
verify(mockRegion, times(1)).remove(eq(1L));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteEntitiesIsCorrect() {
|
public void deleteEntitiesSuccessfully() {
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion();
|
Region<Long, Animal> mockRegion = mockRegion();
|
||||||
|
|
||||||
SimpleGemfireRepository<Animal, Long> repository =
|
SimpleGemfireRepository<Animal, Long> repository =
|
||||||
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
new SimpleGemfireRepository<>(newGemfireTemplate(mockRegion), mockEntityInformation());
|
||||||
|
|
||||||
repository.deleteAll(Arrays.asList(newAnimal(1L, "bird"), newAnimal(2L, "cat"),
|
repository.deleteAll(Arrays.asList(
|
||||||
newAnimal(3L, "dog")));
|
newAnimal(1L, "bird"),
|
||||||
|
newAnimal(2L, "cat"),
|
||||||
|
newAnimal(3L, "dog")
|
||||||
|
));
|
||||||
|
|
||||||
verify(mockRegion, times(1)).remove(eq(1L));
|
verify(mockRegion, times(1)).remove(eq(1L));
|
||||||
verify(mockRegion, times(1)).remove(eq(2L));
|
verify(mockRegion, times(1)).remove(eq(2L));
|
||||||
verify(mockRegion, times(1)).remove(eq(3L));
|
verify(mockRegion, times(1)).remove(eq(3L));
|
||||||
|
verifyNoMoreInteractions(mockRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteAllWithClear() {
|
public void deleteAllWithClear() {
|
||||||
|
|
||||||
Cache mockCache = mockCache("MockCache", false);
|
Cache mockCache = mockCache("MockCache", false);
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.REPLICATE);
|
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.REPLICATE);
|
||||||
@@ -547,6 +806,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteAllWithKeysWhenClearThrowsException() {
|
public void deleteAllWithKeysWhenClearThrowsException() {
|
||||||
|
|
||||||
Cache mockCache = mockCache("MockCache", false);
|
Cache mockCache = mockCache("MockCache", false);
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.PERSISTENT_REPLICATE);
|
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.PERSISTENT_REPLICATE);
|
||||||
@@ -570,6 +830,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteAllWithKeysWhenPartitionRegion() {
|
public void deleteAllWithKeysWhenPartitionRegion() {
|
||||||
|
|
||||||
Cache mockCache = mockCache("MockCache", false);
|
Cache mockCache = mockCache("MockCache", false);
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.PERSISTENT_PARTITION);
|
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.PERSISTENT_PARTITION);
|
||||||
@@ -592,6 +853,7 @@ public class SimpleGemfireRepositoryUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteAllWithKeysWhenTransactionPresent() {
|
public void deleteAllWithKeysWhenTransactionPresent() {
|
||||||
|
|
||||||
Cache mockCache = mockCache("MockCache", true);
|
Cache mockCache = mockCache("MockCache", true);
|
||||||
|
|
||||||
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.REPLICATE);
|
Region<Long, Animal> mockRegion = mockRegion("MockRegion", mockCache, DataPolicy.REPLICATE);
|
||||||
|
|||||||
Reference in New Issue
Block a user