diff --git a/src/main/java/org/springframework/data/gemfire/mapping/GemfireMappingContext.java b/src/main/java/org/springframework/data/gemfire/mapping/GemfireMappingContext.java index 5e445e80..ac13f7d7 100644 --- a/src/main/java/org/springframework/data/gemfire/mapping/GemfireMappingContext.java +++ b/src/main/java/org/springframework/data/gemfire/mapping/GemfireMappingContext.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.data.gemfire.mapping; import java.beans.PropertyDescriptor; @@ -24,9 +25,12 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; /** + * Spring Data {@link AbstractMappingContext} implementation defining entity mapping meta-data + * for GemFire persistent entities. * * @author Oliver Gierke * @author John Blum + * @see org.springframework.data.mapping.context.AbstractMappingContext */ public class GemfireMappingContext extends AbstractMappingContext, GemfirePersistentProperty> { @@ -42,23 +46,23 @@ public class GemfireMappingContext extends AbstractMappingContext GemfirePersistentEntity createPersistentEntity(TypeInformation typeInformation) { - return new GemfirePersistentEntity(typeInformation); + return new GemfirePersistentEntity<>(typeInformation); } - /* - * (non-Javadoc) + /** + * @inheritDoc * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder) */ @Override - protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, + protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, GemfirePersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return new GemfirePersistentProperty(field, descriptor, owner, simpleTypeHolder); + return new GemfirePersistentProperty(field, propertyDescriptor, owner, simpleTypeHolder); } } diff --git a/src/main/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntity.java b/src/main/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntity.java index 74bec9c8..f95d082d 100644 --- a/src/main/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntity.java +++ b/src/main/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntity.java @@ -19,23 +19,16 @@ package org.springframework.data.gemfire.mapping; import static org.springframework.data.gemfire.util.SpringUtils.defaultIfEmpty; import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.gemfire.mapping.annotation.ClientRegion; -import org.springframework.data.gemfire.mapping.annotation.LocalRegion; -import org.springframework.data.gemfire.mapping.annotation.PartitionRegion; import org.springframework.data.gemfire.mapping.annotation.Region; -import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion; -import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.BasicPersistentEntity; -import org.springframework.data.mapping.model.IdPropertyIdentifierAccessor; +import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.TypeInformation; -import org.springframework.util.Assert; /** * {@link PersistentEntity} implementation adding custom GemFire persistent entity related metadata, such as the @@ -54,61 +47,12 @@ public class GemfirePersistentEntity extends BasicPersistentEntity { - - try { - Method getMethod = bean.getClass().getMethod(GET_ID_METHOD_NAME); - - if (getMethod == null) - return null; // getId method not found - - return getMethod.invoke(bean); - } catch (NoSuchMethodException e) { - return null; - } catch (SecurityException e) { - return null; - } catch (IllegalAccessException e) { - return null; - } catch (IllegalArgumentException e) { - return null; - } catch (InvocationTargetException e) { - return null; - } - - }; - - return getIdAccessor; - } - /* (non-Javadoc) */ protected static Annotation resolveRegionAnnotation(Class persistentEntityType) { for (Class regionAnnotationType : Region.REGION_ANNOTATION_TYPES) { - Annotation regionAnnotation = AnnotatedElementUtils.getMergedAnnotation(persistentEntityType, - regionAnnotationType); + Annotation regionAnnotation = AnnotatedElementUtils.getMergedAnnotation( + persistentEntityType, regionAnnotationType); if (regionAnnotation != null) { return regionAnnotation; @@ -122,16 +66,24 @@ public class GemfirePersistentEntity extends BasicPersistentEntity persistentEntityType, Annotation regionAnnotation) { String regionName = (regionAnnotation != null - ? AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(regionAnnotation)).getString("value") - : null); + ? getAnnotationAttributeStringValue(regionAnnotation, "value") : null); return defaultIfEmpty(regionName, persistentEntityType.getSimpleName()); } + /* (non-Javadoc) */ + protected static String getAnnotationAttributeStringValue(Annotation annotation, String attributeName) { + return AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(annotation)) + .getString(attributeName); + } + /** - * Creates a new {@link GemfirePersistentEntity} for the given {@link TypeInformation}. + * Constructs a new instance of {@link GemfirePersistentEntity} initialized with the given {@link TypeInformation} + * describing the domain object (entity) {@link Class} type. * - * @param information must not be {@literal null}. + * @param information {@link TypeInformation} meta-data describing the domain object (entity) {@link Class} type. + * @throws IllegalArgumentException if the given {@link TypeInformation} is {@literal null}. + * @see org.springframework.data.util.TypeInformation */ public GemfirePersistentEntity(TypeInformation information) { super(information); @@ -143,17 +95,17 @@ public class GemfirePersistentEntity extends BasicPersistentEntity concrete {@link Class} type of the Region {@link Annotation}. - * @return the {@link Region} annotation used to annotate this {@link PersistentEntity} or {@literal null} if this - * {@link PersistentEntity} was not annotated with a {@link Region} annotation. - * @see ClientRegion - * @see LocalRegion - * @see PartitionRegion - * @see ReplicateRegion - * @see Region + * @param concrete {@link Class} type of the {@link Region} {@link Annotation}. + * @return the {@link Region} {@link Annotation} used to annotate this {@link PersistentEntity} or {@literal null} + * if this {@link PersistentEntity} was not annotated with a {@link Region} {@link Annotation}. + * @see org.springframework.data.gemfire.mapping.annotation.ClientRegion + * @see org.springframework.data.gemfire.mapping.annotation.LocalRegion + * @see org.springframework.data.gemfire.mapping.annotation.PartitionRegion + * @see org.springframework.data.gemfire.mapping.annotation.ReplicateRegion + * @see org.springframework.data.gemfire.mapping.annotation.Region * @see java.lang.annotation.Annotation */ @SuppressWarnings("unchecked") @@ -162,11 +114,11 @@ public class GemfirePersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity { + protected static final Set SUPPORTED_IDENTIFIER_NAMES = asSet("id"); + /* (non-Javadoc) */ private static SimpleTypeHolder resolveSimpleTypeHolder(SimpleTypeHolder source) { return (source instanceof GemfireSimpleTypeHolder ? source @@ -39,26 +46,59 @@ public class GemfirePersistentProperty extends AnnotationBasedPersistentProperty } /** - * Constructs an instance of the GemfirePersistentProperty with entity information. + * Constructs an instance of the {@link GemfirePersistentProperty} initialized with entity + * persistent property information (meta-data). * - * @param field the entity field corresponding to the persistent property. - * @param propertyDescriptor PropertyDescriptor for the entity's persistent property. - * @param owner the entity owning the persistent property. - * @param simpleTypeHolder type holder for primitive types. + * @param field entity {@link Field} corresponding to the persistent property. + * @param propertyDescriptor {@link PropertyDescriptor} for the entity's persistent property. + * @param owner entity owning the persistent property. + * @param simpleTypeHolder {@link SimpleTypeHolder} used to handle primitive types. + * @see org.springframework.data.mapping.model.SimpleTypeHolder + * @see org.springframework.data.mapping.PersistentEntity + * @see java.beans.PropertyDescriptor + * @see java.lang.reflect.Field */ public GemfirePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + super(field, propertyDescriptor, owner, resolveSimpleTypeHolder(simpleTypeHolder)); } - /* - * (non-Javadoc) - * - * @see org.springframework.data.mapping.model.AbstractPersistentProperty# - * createAssociation() + /** + * @inheritDoc */ @Override protected Association createAssociation() { - return new Association(this, null); + return new Association<>(this, null); + } + + /** + * Determines whether this {@link GemfirePersistentProperty} explicitly identifies an entity property identifier, + * one in which the user explicitly annotated a entity class member (field or getter/setter). + * + * @return a boolean value indicating whether this {@link GemfirePersistentProperty} explicitly identifies + * an entity property identifier. + * @see org.springframework.data.annotation.Id + * @see #isAnnotationPresent(Class) + */ + public boolean isExplicitIdProperty() { + return isAnnotationPresent(Id.class); + } + + /** + * @inheritDoc + * @see org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isIdProperty() + */ + @Override + public boolean isIdProperty() { + return (super.isIdProperty() || SUPPORTED_IDENTIFIER_NAMES.contains(getName())); + } + + /** + * @inheritDoc + */ + @Override + public boolean usePropertyAccess() { + return (super.usePropertyAccess() || (getField() == null && this.propertyDescriptor != null)); } } diff --git a/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java b/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java index 0035b15b..29011570 100644 --- a/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java +++ b/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java @@ -178,14 +178,14 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw */ @Override public Object fromData(final Class type, final PdxReader reader) { + final GemfirePersistentEntity entity = getPersistentEntity(type); final Object instance = getInstantiatorFor(entity).createInstance(entity, - new PersistentEntityParameterValueProvider(entity, - new GemfirePropertyValueProvider(reader), null)); + new PersistentEntityParameterValueProvider<>(entity, new GemfirePropertyValueProvider(reader), null)); - final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), - getConversionService()); + final PersistentPropertyAccessor propertyAccessor = + new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), getConversionService()); entity.doWithProperties(new PropertyHandler() { public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) { @@ -209,7 +209,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw log.debug(String.format("with value [%1$s]", value)); } - accessor.setProperty(persistentProperty, value); + propertyAccessor.setProperty(persistentProperty, value); } catch (Exception e) { throw new MappingException(String.format( @@ -221,7 +221,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw } }); - return accessor.getBean(); + return propertyAccessor.getBean(); } /** @@ -229,39 +229,40 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw */ @Override public boolean toData(final Object value, final PdxWriter writer) { - GemfirePersistentEntity entity = getPersistentEntity(value.getClass()); - final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(value), - getConversionService()); + GemfirePersistentEntity entity = getPersistentEntity(value); + + final PersistentPropertyAccessor propertyAccessor = + new ConvertingPropertyAccessor(entity.getPropertyAccessor(value), getConversionService()); entity.doWithProperties(new PropertyHandler() { - @Override - @SuppressWarnings("unchecked") + @Override @SuppressWarnings("unchecked") public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) { PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType()); Object propertyValue = null; try { - propertyValue = accessor.getProperty(persistentProperty); + propertyValue = propertyAccessor.getProperty(persistentProperty); if (log.isDebugEnabled()) { - log.debug(String.format("serializing value [%1$s] of property [%2$s] for entity of type [%3$s] to PDX%4$s", - propertyValue, persistentProperty.getName(), value.getClass(), (customSerializer != null ? - String.format(" using custom PdxSerializer [%1$s]", customSerializer) : ""))); + log.debug(String.format("Serializing entity property [%1$s] value [%2$s] of type [%3$s] to PDX%4$s", + persistentProperty.getName(), propertyValue, value.getClass(), (customSerializer != null ? + String.format(" using custom PdxSerializer [%s]", customSerializer) : ""))); } if (customSerializer != null) { customSerializer.toData(propertyValue, writer); } else { - writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType()); + writer.writeField(persistentProperty.getName(), propertyValue, + (Class) persistentProperty.getType()); } } catch (Exception e) { throw new MappingException(String.format( - "while serializing value [%1$s] of property [%2$s] for entity of type [%3$s] to PDX%4$s", - propertyValue, persistentProperty.getName(), value.getClass(), + "Error while serializing entity property [%1$s] value [%2$s] of type [%3$s] to PDX%4$s", + persistentProperty.getName(), propertyValue, value.getClass(), (customSerializer != null ? String.format(" using custom PdxSerializer [%1$s].", customSerializer.getClass().getName()) : ".")), e); } @@ -304,12 +305,24 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw } /** - * Looks up and returns the PersistentEntity meta-data for the given entity class type. + * Looks up and returns the {@link PersistentEntity} meta-data for the given entity object. * - * @param entityType the Class type of the actual persistent entity, application domain object class. - * @return the PersistentEntity meta-data for the given entity class type. - * @see #getMappingContext() + * @param entity actual persistent entity, application domain object. + * @return the {@link PersistentEntity} meta-data for the given entity object. * @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity + * @see #getPersistentEntity(Class) + */ + protected GemfirePersistentEntity getPersistentEntity(Object entity) { + return getPersistentEntity(entity.getClass()); + } + + /** + * Looks up and returns the {@link PersistentEntity} meta-data for the given entity {@link Class} type. + * + * @param entityType {@link Class} type of the actual persistent entity, application domain object {@link Class}. + * @return the {@link PersistentEntity} meta-data for the given entity {@link Class} type. + * @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity + * @see #getMappingContext() */ protected GemfirePersistentEntity getPersistentEntity(Class entityType) { return getMappingContext().getPersistentEntity(entityType); diff --git a/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java index 0af0596b..e11556eb 100644 --- a/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java @@ -16,6 +16,8 @@ package org.springframework.data.gemfire.util; +import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -82,6 +84,26 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio return Collections.unmodifiableSet(set); } + /** + * Null-safe method to determines whether the given {@link Collection} contains any elements from the given array. + * + * @param collection {@link Collection} to evaluate + * @param elements array of elements to evaluate. + * @return a boolean value indicating whether the collection contains at least 1 element from the given array. + * @see java.util.Collection#contains(Object) + */ + public static boolean containsAny(Collection collection, Object... elements) { + if (collection != null) { + for (Object element : nullSafeArray(elements, Object.class)) { + if (collection.contains(element)) { + return true; + } + } + } + + return false; + } + /** * Returns the given {@link Iterable} if not {@literal null} or empty, otherwise returns the {@code defaultIterable}. * diff --git a/src/test/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntityUnitTests.java b/src/test/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntityUnitTests.java index 102de920..0c38e8f7 100644 --- a/src/test/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntityUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/mapping/GemfirePersistentEntityUnitTests.java @@ -13,129 +13,204 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.data.gemfire.mapping; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import java.math.BigDecimal; import java.math.BigInteger; -import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.data.annotation.Id; import org.springframework.data.gemfire.mapping.annotation.Region; import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.context.MappingContext; +import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.ClassTypeInformation; -import lombok.Data; - /** * Unit tests for {@link GemfirePersistentEntity}. * * @author Oliver Gierke * @author John Blum + * @author Gregory Green + * @see org.junit.Rule + * @see org.junit.Test + * @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity */ public class GemfirePersistentEntityUnitTests { - protected MappingContext, GemfirePersistentProperty> getMappingContext() { - return new GemfireMappingContext(); + @Rule + public ExpectedException exception = ExpectedException.none(); + + private GemfireMappingContext mappingContext = new GemfireMappingContext(); + + protected IdentifierAccessor getIdentifierAccessor(Object domainObject) { + return getMappingContextPersistentEntity(domainObject).getIdentifierAccessor(domainObject); } - /** - * JIRA ticket SGF-582 - * - * Used an object's getId method if the @Id does not exists - */ - @Test - public void supportsGetId() { - - GemfirePersistentEntity unnamedRegionEntity = new GemfirePersistentEntity( - ClassTypeInformation.from(UnannotatedRegion.class)); + @SuppressWarnings("unchecked") + protected GemfirePersistentEntity getMappingContextPersistentEntity(Object domainObject) { + return this.getMappingContextPersistentEntity((Class) domainObject.getClass()); + } - IdentifierAccessor accessor = unnamedRegionEntity.getIdentifierAccessor(new UnannotatedRegion()); - Assert.assertNull(accessor.getIdentifier()); - - GemfirePersistentEntity entity = new GemfirePersistentEntity( - ClassTypeInformation.from(NotAnnotationIdRegion.class)); - - NotAnnotationIdRegion region = new NotAnnotationIdRegion(); - - region.setId("id"); - region.setValue("value"); - - accessor = entity.getIdentifierAccessor(region); - - Assert.assertNotNull(accessor.getIdentifier()); - - Assert.assertEquals("id", accessor.getIdentifier()); + @SuppressWarnings("unchecked") + protected GemfirePersistentEntity getMappingContextPersistentEntity(Class type) { + return (GemfirePersistentEntity) this.mappingContext.getPersistentEntity(type); + } + protected GemfirePersistentEntity newPersistentEntity(Class type) { + return new GemfirePersistentEntity<>(ClassTypeInformation.from(type)); } @Test - public void defaultsRegionNameToClassName() { - GemfirePersistentEntity entity = new GemfirePersistentEntity( - ClassTypeInformation.from(UnannotatedRegion.class)); - assertThat(entity.getRegionName(), is(UnannotatedRegion.class.getSimpleName())); + public void defaultsRegionNameForNonRegionAnnotatedEntityToClassName() { + assertThat(newPersistentEntity(NonRegionAnnotatedEntity.class).getRegionName()) + .isEqualTo(NonRegionAnnotatedEntity.class.getSimpleName()); } @Test - public void defaultsAnnotatedRegionToCLassName() { - GemfirePersistentEntity entity = new GemfirePersistentEntity( - ClassTypeInformation.from(UnnamedRegion.class)); - assertThat(entity.getRegionName(), is(UnnamedRegion.class.getSimpleName())); + public void defaultsRegionNameForUnnamedRegionAnnotatedEntityToClassName() { + assertThat(newPersistentEntity(UnnamedRegionAnnotatedEntity.class).getRegionName()) + .isEqualTo(UnnamedRegionAnnotatedEntity.class.getSimpleName()); } @Test - public void readsRegionNameFromAnnotation() { - - GemfirePersistentEntity entity = new GemfirePersistentEntity( - ClassTypeInformation.from(AnnotatedRegion.class)); - assertThat(entity.getRegionName(), is("Foo")); + public void returnsGivenNameForNamedRegionAnnotatedEntityAsRegionName() { + assertThat(newPersistentEntity(NamedRegionAnnotatedEntity.class).getRegionName()).isEqualTo("Foo"); } @Test @SuppressWarnings("unchecked") - public void bigDecimalPersistentPropertyIsNotEntity() { - GemfirePersistentEntity entity = (GemfirePersistentEntity) getMappingContext() - .getPersistentEntity(ExampleDomainObject.class); + public void bigDecimalPersistentPropertyIsNotAnEntity() { + GemfirePersistentEntity entity = + getMappingContextPersistentEntity(ExampleDomainObject.class); - assertThat(entity.getRegionName(), is(equalTo("Example"))); + assertThat(entity).isNotNull(); + assertThat(entity.getRegionName()).isEqualTo("Example"); GemfirePersistentProperty currency = entity.getPersistentProperty("currency"); - assertThat(currency, is(notNullValue())); - assertThat(currency.isEntity(), is(false)); + assertThat(currency).isNotNull(); + assertThat(currency.isEntity()).isFalse(); } @Test @SuppressWarnings("unchecked") - public void bigIntegerPersistentPropertyIsNotEntity() { - GemfirePersistentEntity entity = (GemfirePersistentEntity) getMappingContext() - .getPersistentEntity(ExampleDomainObject.class); + public void bigIntegerPersistentPropertyIsNotAnEntity() { + GemfirePersistentEntity entity = + getMappingContextPersistentEntity(ExampleDomainObject.class); - assertThat(entity.getRegionName(), is(equalTo("Example"))); + assertThat(entity).isNotNull(); + assertThat(entity.getRegionName()).isEqualTo("Example"); GemfirePersistentProperty bigNumber = entity.getPersistentProperty("bigNumber"); - assertThat(bigNumber, is(notNullValue())); - assertThat(bigNumber.isEntity(), is(false)); + assertThat(bigNumber).isNotNull(); + assertThat(bigNumber.isEntity()).isFalse(); } - static class UnannotatedRegion {} + /** + * SGF-582 + */ + @Test + public void identifierForNonIdAnnotatedEntityWithNoIdFieldOrPropertyIsNull() { + IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonRegionAnnotatedEntity()); + + assertThat(identifierAccessor).isNotNull(); + assertThat(identifierAccessor.getIdentifier()).isNull(); + } + + /** + * SGF-582 + */ + @Test + public void identifierForNonIdAnnotatedEntityWithIdFieldIsNotNull() { + IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonIdAnnotatedIdFieldEntity()); + + assertThat(identifierAccessor.getIdentifier()).isNotNull(); + assertThat(identifierAccessor.getIdentifier()).isEqualTo(123L); + } + + /** + * SGF-582 + */ + @Test + public void identifierForNonIdAnnotatedEntityWithIdPropertyIsNotNull() { + IdentifierAccessor identifierAccessor = getIdentifierAccessor(new NonIdAnnotatedIdGetterEntity()); + + assertThat(identifierAccessor).isNotNull(); + assertThat(identifierAccessor.getIdentifier()).isEqualTo(456L); + } + + @Test + public void identifierForIdAnnotatedFieldAndPropertyEntityShouldNotConflict() { + IdentifierAccessor identifierAccessor = getIdentifierAccessor(new IdAnnotatedFieldAndPropertyEntity()); + + assertThat(identifierAccessor).isNotNull(); + assertThat(identifierAccessor.getIdentifier()).isEqualTo(1L); + } + + @Test + public void identifierForAmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntityThrowsMappingException() { + AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity entity + = new AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity(); + + String expectedMessage = String.format("Attempt to add explicit id property [ssn] but already have id property [id] registered as explicit;" + + " Please check your object [%s] mapping configuration", entity.getClass().getName()); + + exception.expect(MappingException.class); + exception.expectCause(is(nullValue(Throwable.class))); + exception.expectMessage(expectedMessage); + + getIdentifierAccessor(new AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity()); + } + + static class AmbiguousIdAnnotatedFieldAndIdAnnotatedPropertyEntity { + + @Id + private Long id = 1L; + + @Id + public String getSsn() { + return "123456789"; + } + } + + static class IdAnnotatedFieldAndPropertyEntity { + + @Id + private Long id = 1L; + + @Id + public Long getId() { + return this.id; + } + } + + static class NonIdAnnotatedIdFieldEntity { + private Long id = 123L; + } + + static class NonIdAnnotatedIdGetterEntity { + public Long getId() { + return 456L; + } + } + + static class NonRegionAnnotatedEntity { + } @Region("Foo") - static class AnnotatedRegion {} + static class NamedRegionAnnotatedEntity { + } @Region - static class UnnamedRegion {} - - static @Data class NotAnnotationIdRegion { - - private String value; - private String id; + static class UnnamedRegionAnnotatedEntity { } @Region("Example") @@ -154,5 +229,4 @@ public class GemfirePersistentEntityUnitTests { return bigNumber; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java index 3cbc4db4..00fbe370 100644 --- a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java @@ -154,8 +154,7 @@ public class MappingPdxSerializerUnitTests { when(mockInstantiator.createInstance(any(GemfirePersistentEntity.class), any(ParameterValueProvider.class))) .thenReturn(person); - serializer.setGemfireInstantiators(Collections., EntityInstantiator>singletonMap( - Person.class, mockInstantiator)); + serializer.setGemfireInstantiators(Collections.singletonMap(Person.class, mockInstantiator)); serializer.fromData(Person.class, mockReader); @@ -258,7 +257,7 @@ public class MappingPdxSerializerUnitTests { expectedException.expect(MappingException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); expectedException.expectMessage(String.format( - "while serializing value [Portland, 12345] of property [address] for entity of type [%1$s] to PDX", + "Error while serializing entity property [address] value [Portland, 12345] of type [%s] to PDX", Person.class)); new MappingPdxSerializer(context, conversionService).toData(jonDoe, mockWriter); diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/Person.java b/src/test/java/org/springframework/data/gemfire/repository/sample/Person.java index a57d56ca..ed2bd300 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/sample/Person.java +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/Person.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.Transient; import org.springframework.data.gemfire.mapping.annotation.Region; import org.springframework.util.ObjectUtils; @@ -107,6 +108,7 @@ public class Person implements Serializable { * @see #getFirstname() * @see #getLastname() */ + @Transient public String getName() { return String.format("%1$s %2$s", getFirstname(), getLastname()); } diff --git a/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java index 226d8c39..818b52d0 100644 --- a/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java @@ -63,8 +63,8 @@ public class CollectionUtilsUnitTests { @Test public void addAllIterableElementsToList() { - List target = new ArrayList(Arrays.asList(1, 2, 3)); - Set source = new HashSet(Arrays.asList(1, 2, 3)); + List target = new ArrayList<>(Arrays.asList(1, 2, 3)); + Set source = new HashSet<>(Arrays.asList(1, 2, 3)); target = CollectionUtils.addAll(target, source); @@ -75,8 +75,8 @@ public class CollectionUtilsUnitTests { @Test public void addAllIterableElementsToSet() { - Set target = new HashSet(Arrays.asList(1, 2, 3)); - Set source = new HashSet(Arrays.asList(1, 2, 3, 4, 5)); + Set target = new HashSet<>(Arrays.asList(1, 2, 3)); + Set source = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)); target = CollectionUtils.addAll(target, source); @@ -96,9 +96,9 @@ public class CollectionUtilsUnitTests { @Test public void addEmptyIterableToCollection() { - Collection target = new ArrayList(Arrays.asList(1, 2, 3)); + Collection target = new ArrayList<>(Arrays.asList(1, 2, 3)); - target = CollectionUtils.addAll(target, Collections.emptyList()); + target = CollectionUtils.addAll(target, Collections.emptyList()); assertThat(target).isNotNull(); assertThat(target.size()).isEqualTo(3); @@ -107,7 +107,7 @@ public class CollectionUtilsUnitTests { @Test public void addNullIterableToCollection() { - Collection target = new ArrayList(Arrays.asList(1, 2, 3)); + Collection target = new ArrayList<>(Arrays.asList(1, 2, 3)); target = CollectionUtils.addAll(target, null); @@ -156,10 +156,30 @@ public class CollectionUtilsUnitTests { } } + @Test + public void containsAnyWithCollectionAndArrayIsTrue() { + assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), 1, 2)).isTrue(); + } + + @Test + public void containsAnyWithCollectionAndArrayIsFalse() { + assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), 4)).isFalse(); + } + + @Test + public void containsAnyWithCollectionAndNullArrayIsFalse() { + assertThat(CollectionUtils.containsAny(Arrays.asList(1, 2, 3), (Object[]) null)); + } + + @Test + public void containsAnyWithNullCollectionAndArrayIsFalse() { + assertThat(CollectionUtils.containsAny(null, 1)).isFalse(); + } + @Test public void defaultIfEmptyWithNonNullNonEmptyIterableReturnsIterable() { - Iterable iterable = Collections.singleton(1); - Iterable defaultIterable = Collections.singleton(2); + Iterable iterable = Collections.singleton(1); + Iterable defaultIterable = Collections.singleton(2); assertThat(CollectionUtils.defaultIfEmpty(iterable, defaultIterable)).isSameAs(iterable); } @@ -167,7 +187,7 @@ public class CollectionUtilsUnitTests { @Test public void defaultIfEmptyWithEmptyIterableReturnsDefault() { Iterable iterable = Collections.emptySet(); - Iterable defaultIterable = Collections.singleton(2); + Iterable defaultIterable = Collections.singleton(2); assertThat(CollectionUtils.defaultIfEmpty(iterable, defaultIterable)).isSameAs(defaultIterable); }