Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>4.1.0-SNAPSHOT</version>
<version>4.1.0-GH-3441-SNAPSHOT</version>

<name>Spring Data Core</name>
<description>Core Spring concepts underpinning every Spring Data module.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public MappingAuditableBeanWrapperFactory(PersistentEntities entities) {

this.entities = entities;
this.metadataCache = new ConcurrentHashMap<>();

entities
.forEach(it -> entities.mapOnContext(it.getType(), (context, entity) -> getMetadata(context, it.getType())));
}

@Override
Expand All @@ -82,20 +85,26 @@ public <T> Optional<AuditableBeanWrapper<T>> getBeanWrapperFor(T source) {
return super.getBeanWrapperFor(source);
}

return entities.mapOnContext(it.getClass(), (context, entity) -> {
Class<?> entityClass = it.getClass();
return entities.mapOnContext(entityClass, (context, entity) -> {

MappingAuditingMetadata metadata = metadataCache.computeIfAbsent(it.getClass(),
key -> new MappingAuditingMetadata(context, it.getClass()));
MappingAuditingMetadata metadata = getMetadata(context, entityClass);

return Optional.<AuditableBeanWrapper<T>> ofNullable(metadata.isAuditable() //
? new MappingMetadataAuditableBeanWrapper<>(getConversionService(), entity.getPropertyPathAccessor(it),
metadata)
: null);
if (metadata.isAuditable()) {
return Optional.<AuditableBeanWrapper<T>> of(new MappingMetadataAuditableBeanWrapper<>(getConversionService(),
entity.getPropertyPathAccessor(it), metadata));
}

return Optional.<AuditableBeanWrapper<T>> empty();
}).orElseGet(() -> super.getBeanWrapperFor(source));
});
}

private MappingAuditingMetadata getMetadata(MappingContext<?, ? extends PersistentProperty<?>> context,
Class<?> entityClass) {
return metadataCache.computeIfAbsent(entityClass, key -> new MappingAuditingMetadata(context, entityClass));
}

/**
* Captures {@link PersistentProperty} instances equipped with auditing annotations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,24 +136,29 @@ public static PersistentEntities of(MappingContext<?, ?>... contexts) {
* @return result of the {@link BiFunction}.
*/
public <T> Optional<T> mapOnContext(Class<?> type,
BiFunction<MappingContext<?, ? extends PersistentProperty<?>>, PersistentEntity<?, ?>, T> combiner) {
BiFunction<MappingContext<?, ? extends PersistentProperty<?>>, PersistentEntity<?, ?>, @Nullable T> combiner) {

Assert.notNull(type, "Type must not be null");
Assert.notNull(combiner, "Combining BiFunction must not be null");

Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>> mappingContexts = getMappingContexts();

if (mappingContexts.size() == 1) {
return mappingContexts.stream() //
.filter(it -> it.getPersistentEntity(type) != null) //
.map(it -> combiner.apply(it, it.getRequiredPersistentEntity(type))) //
.findFirst();
for (MappingContext<?, ? extends PersistentProperty<?>> it : mappingContexts) {
if (it.getPersistentEntity(type) != null) {
return Optional.ofNullable(combiner.apply(it, it.getRequiredPersistentEntity(type)));
}
}
return Optional.empty();
}

for (MappingContext<?, ? extends PersistentProperty<?>> it : mappingContexts) {
if (it.hasPersistentEntityFor(type)) {
return Optional.ofNullable(combiner.apply(it, it.getRequiredPersistentEntity(type)));
}
}

return mappingContexts.stream() //
.filter(it -> it.hasPersistentEntityFor(type)) //
.map(it -> combiner.apply(it, it.getRequiredPersistentEntity(type))) //
.findFirst();
return Optional.empty();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@

import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mapping.context.SampleMappingContext;
Expand All @@ -34,24 +34,18 @@
* Unit test for {@code AuditingHandler}.
*
* @author Oliver Gierke
* @author Mark Paluch
* @since 1.5
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests {

SampleMappingContext mappingContext;

@BeforeEach
void init() {

this.mappingContext = new SampleMappingContext();
this.mappingContext.getPersistentEntity(AuditedUser.class);
this.mappingContext.afterPropertiesSet();
}

@Override
protected IsNewAwareAuditingHandler getHandler() {
SampleMappingContext mappingContext = new SampleMappingContext();
mappingContext.getPersistentEntity(AuditedUser.class);
mappingContext.afterPropertiesSet();
return new IsNewAwareAuditingHandler(PersistentEntities.of(mappingContext));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@
import org.springframework.data.domain.Auditable;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mapping.context.SampleMappingContext;
import org.springframework.test.util.ReflectionTestUtils;

/**
* Unit tests for {@link MappingAuditableBeanWrapperFactory}.
*
* @author Oliver Gierke
* @author Jens Schauder
* @author Mark Paluch
* @since 1.8
*/
class MappingAuditableBeanWrapperFactoryUnitTests {
Expand All @@ -69,6 +71,13 @@ void setUp() {
factory = new MappingAuditableBeanWrapperFactory(entities);
}

@Test // GH-3441
void cacheWarmedWithKnownPersistentEntities() {

Map<?, ?> metadataCache = (Map<?, ?>) ReflectionTestUtils.getField(factory, "metadataCache");
assertThat(metadataCache).hasSize(4);
}

@Test // DATACMNS-365
void discoversAuditingPropertyOnField() {

Expand Down
Loading