DATAGRAPH-1212 - Improve fallback IsNewStrategy.
This change replaces the previous fallback IsNewStrategy with a backport from SDN/RX respectivley SDN 6. This takes much better care of handling externally assigned and primitive ids together with version properties and fails fast when it can’t cater for a scenario. In addition to the required OGM update, this makes it possible to audit entities with externally generated or assigned ids. For this scenario, tests have been added as well.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.neo4j.ogm.id.InternalIdStrategy;
|
||||
import org.neo4j.ogm.metadata.ClassInfo;
|
||||
import org.neo4j.ogm.metadata.MetaData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.support.IsNewStrategy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of a {@link IsNewStrategy} that follows our supported identifiers and generators. Entities will be
|
||||
* treated as new:
|
||||
* <ul>
|
||||
* <li>when using internally generated (database) ids and the id property is {@literal null} or of a numeric primitive
|
||||
* less than or equal {@literal 0},</li>
|
||||
* <li>when using externally generated values and the id is {@literal null},</li>
|
||||
* <li>when using assigned values without a version property or with a version property that is {@literal null}.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* An entity will not be treated as new
|
||||
* <ul>
|
||||
* <li>when using internally generated (database) ids and the id property has a non-null value greater than
|
||||
* {@literal 0},</li>
|
||||
* <li>when using externally generated values and the id property is not {@literal null},</li>
|
||||
* <li>when using assigned values together with {@link org.springframework.data.annotation.Version @Version} which has
|
||||
* already a value not equal to {@literal null} or {@literal 0}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @since 5.1.20
|
||||
*/
|
||||
class DefaultNeo4jIsNewStrategy implements IsNewStrategy {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultNeo4jIsNewStrategy.class);
|
||||
|
||||
static IsNewStrategy basedOn(Neo4jPersistentEntity<?> entity, MetaData ogmMetadata) {
|
||||
|
||||
Assert.notNull(entity, "Entity meta data must not be null.");
|
||||
|
||||
ClassInfo classInfo = ogmMetadata.classInfo(entity.getType());
|
||||
boolean internallyGeneratedId = classInfo.hasIdentityField();
|
||||
boolean externallyGeneratedId =
|
||||
classInfo.idStrategyClass() != null && InternalIdStrategy.class != classInfo.idStrategyClass();
|
||||
boolean assignedId = !internallyGeneratedId && classInfo.idStrategyClass() == null;
|
||||
|
||||
Class<?> valueType;
|
||||
if (classInfo.hasIdentityField()) {
|
||||
valueType = classInfo.identityField().type();
|
||||
} else if (classInfo.hasPrimaryIndexField()) {
|
||||
valueType = classInfo.primaryIndexField().type();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
String.format("Required identifier property not found for %s!", entity.getType()));
|
||||
}
|
||||
|
||||
if (externallyGeneratedId && valueType.isPrimitive()) {
|
||||
throw new IllegalArgumentException(String.format("Cannot use %s with externally generated, primitive ids.",
|
||||
DefaultNeo4jIsNewStrategy.class.getName()));
|
||||
}
|
||||
|
||||
Function<Object, Object> valueLookup;
|
||||
Neo4jPersistentProperty versionProperty = entity.getVersionProperty();
|
||||
if (assignedId) {
|
||||
if (versionProperty == null) {
|
||||
log.warn("Instances of " + entity.getType()
|
||||
+ " with an assigned id will always be treated as new without version property!");
|
||||
valueType = Void.class;
|
||||
valueLookup = source -> null;
|
||||
} else {
|
||||
valueType = versionProperty.getType();
|
||||
valueLookup = source -> entity.getPropertyAccessor(source).getProperty(versionProperty);
|
||||
}
|
||||
} else {
|
||||
valueLookup = source -> entity.getIdentifierAccessor(source).getIdentifier();
|
||||
}
|
||||
|
||||
return new DefaultNeo4jIsNewStrategy(internallyGeneratedId, externallyGeneratedId, assignedId, valueType,
|
||||
valueLookup);
|
||||
}
|
||||
|
||||
private final boolean internallyGeneratedId;
|
||||
|
||||
private final boolean externallyGeneratedId;
|
||||
|
||||
private final boolean assignedId;
|
||||
|
||||
private final Class<?> valueType;
|
||||
|
||||
private @Nullable final Function<Object, Object> valueLookup;
|
||||
|
||||
private DefaultNeo4jIsNewStrategy(boolean internallyGeneratedId, boolean externallyGeneratedId, boolean assignedId,
|
||||
Class<?> valueType, @Nullable Function<Object, Object> valueLookup) {
|
||||
this.internallyGeneratedId = internallyGeneratedId;
|
||||
this.externallyGeneratedId = externallyGeneratedId;
|
||||
this.assignedId = assignedId;
|
||||
this.valueType = valueType;
|
||||
this.valueLookup = valueLookup;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see IsNewStrategy#isNew(Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean isNew(Object entity) {
|
||||
|
||||
Object value = valueLookup.apply(entity);
|
||||
if (internallyGeneratedId) {
|
||||
return value == null || (value instanceof Long && ((Long) value) < 0);
|
||||
} else if (externallyGeneratedId) {
|
||||
return value == null;
|
||||
} else if (assignedId) {
|
||||
if (valueType != null && !valueType.isPrimitive()) {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
if (Number.class.isInstance(value)) {
|
||||
return ((Number) value).longValue() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Could not determine whether %s is new! Unsupported identifier or version property!",
|
||||
entity));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class Neo4jMappingContext extends AbstractMappingContext<Neo4jPersistentE
|
||||
@Override
|
||||
protected <T> Neo4jPersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
logger.debug("Creating Neo4jPersistentEntity from type information: {}", typeInformation);
|
||||
return new Neo4jPersistentEntity<>(typeInformation);
|
||||
return new Neo4jPersistentEntity<>(typeInformation, this.metaData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.neo4j.mapping;
|
||||
|
||||
import org.neo4j.ogm.metadata.MetaData;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty.PropertyType;
|
||||
import org.springframework.data.support.IsNewStrategy;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
@@ -47,13 +48,17 @@ import org.springframework.data.util.TypeInformation;
|
||||
*/
|
||||
public class Neo4jPersistentEntity<T> extends BasicPersistentEntity<T, Neo4jPersistentProperty> {
|
||||
|
||||
private final Lazy<IsNewStrategy> fallbackIsNewStrategy;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Neo4jPersistentEntity} based on the given type information.
|
||||
*
|
||||
* @param information The {@link TypeInformation} upon which to base this persistent entity.
|
||||
*/
|
||||
Neo4jPersistentEntity(TypeInformation<T> information) {
|
||||
Neo4jPersistentEntity(TypeInformation<T> information, MetaData metaData) {
|
||||
|
||||
super(information);
|
||||
this.fallbackIsNewStrategy = Lazy.of(() -> DefaultNeo4jIsNewStrategy.basedOn(this, metaData));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -62,7 +67,7 @@ public class Neo4jPersistentEntity<T> extends BasicPersistentEntity<T, Neo4jPers
|
||||
*/
|
||||
@Override
|
||||
protected IsNewStrategy getFallbackIsNewStrategy() {
|
||||
return new Neo4jIsNewStrategy(this);
|
||||
return fallbackIsNewStrategy.get();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -91,33 +96,4 @@ public class Neo4jPersistentEntity<T> extends BasicPersistentEntity<T, Neo4jPers
|
||||
}
|
||||
return preferredIdProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link IsNewStrategy} to also consider entities with identifiers of negative Long values new.
|
||||
* See also DATAGRAPH-1031.
|
||||
*
|
||||
* @author Frantisek Hartman
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class Neo4jIsNewStrategy implements IsNewStrategy {
|
||||
|
||||
private final Neo4jPersistentEntity<?> entity;
|
||||
|
||||
private Neo4jIsNewStrategy(Neo4jPersistentEntity<?> entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.support.IsNewStrategy#isNew(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean isNew(Object bean) {
|
||||
|
||||
PersistentProperty<? extends PersistentProperty<?>> property = entity.getRequiredIdProperty();
|
||||
Object value = entity.getPropertyAccessor(bean).getProperty(property);
|
||||
|
||||
return value == null || (value instanceof Long && ((Long) value) < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +187,6 @@ public class Neo4jPersistentProperty extends AnnotationBasedPersistentProperty<N
|
||||
|
||||
@Override
|
||||
protected Association<Neo4jPersistentProperty> createAssociation() {
|
||||
return new Association<Neo4jPersistentProperty>(this, null);
|
||||
return new Association<>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.neo4j.auditing;
|
||||
|
||||
import static java.util.Optional.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static java.util.Optional.of;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.within;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
@@ -30,6 +31,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.neo4j.annotation.EnableNeo4jAuditing;
|
||||
import org.springframework.data.neo4j.auditing.domain.User;
|
||||
import org.springframework.data.neo4j.auditing.domain.UserCustomIdStrategy;
|
||||
import org.springframework.data.neo4j.auditing.repository.UserCustomIdStrategyRepository;
|
||||
import org.springframework.data.neo4j.auditing.repository.UserRepository;
|
||||
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -57,6 +60,8 @@ public class JavaConfigurationAuditingTests {
|
||||
|
||||
@Autowired private UserRepository userRepository;
|
||||
|
||||
@Autowired private UserCustomIdStrategyRepository userCustomIdStrategyRepository;
|
||||
|
||||
@Test
|
||||
public void whenSaveEntity_thenSetCreatedAndCreatedBy() {
|
||||
User user = new User("John Doe");
|
||||
@@ -89,4 +94,38 @@ public class JavaConfigurationAuditingTests {
|
||||
assertThat(found.getModified()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
|
||||
assertThat(found.getModifiedBy()).isEqualTo("userId");
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-1212
|
||||
public void shouldAuditEntitiesWithCustomIdStrategyOnCreation() {
|
||||
|
||||
UserCustomIdStrategy user = new UserCustomIdStrategy("John Doe");
|
||||
userCustomIdStrategyRepository.save(user);
|
||||
|
||||
Optional<UserCustomIdStrategy> loaded = userCustomIdStrategyRepository.findById(user.getId());
|
||||
assertThat(loaded).hasValueSatisfying(found -> {
|
||||
|
||||
assertThat(found.getCreated()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
|
||||
assertThat(found.getCreatedBy()).isEqualTo("userId");
|
||||
|
||||
assertThat(found.getModified()).isNull();
|
||||
assertThat(found.getModifiedBy()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-1212
|
||||
public void shouldAuditEntitiesWithCustomIdStrategyOnUpdate() {
|
||||
|
||||
UserCustomIdStrategy user = new UserCustomIdStrategy("John Doe");
|
||||
userCustomIdStrategyRepository.save(user);
|
||||
|
||||
user.setName("Johan Doe");
|
||||
userCustomIdStrategyRepository.save(user);
|
||||
|
||||
Optional<UserCustomIdStrategy> loaded = userCustomIdStrategyRepository.findById(user.getId());
|
||||
assertThat(loaded).hasValueSatisfying(found -> {
|
||||
|
||||
assertThat(found.getModified()).isNotNull().isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
|
||||
assertThat(found.getModifiedBy()).isEqualTo("userId");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.auditing.domain;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
import org.neo4j.ogm.annotation.typeconversion.Convert;
|
||||
import org.neo4j.ogm.id.UuidStrategy;
|
||||
import org.neo4j.ogm.typeconversion.UuidStringConverter;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
@NodeEntity
|
||||
public class UserCustomIdStrategy {
|
||||
|
||||
@Id @GeneratedValue(strategy = UuidStrategy.class) @Convert(UuidStringConverter.class)
|
||||
UUID id;
|
||||
|
||||
String name;
|
||||
|
||||
@CreatedDate LocalDateTime created;
|
||||
|
||||
@CreatedBy String createdBy;
|
||||
|
||||
@LastModifiedDate LocalDateTime modified;
|
||||
|
||||
@LastModifiedBy String modifiedBy;
|
||||
|
||||
public UserCustomIdStrategy(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(LocalDateTime created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public LocalDateTime getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(LocalDateTime modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public String getModifiedBy() {
|
||||
return modifiedBy;
|
||||
}
|
||||
|
||||
public void setModifiedBy(String modifiedBy) {
|
||||
this.modifiedBy = modifiedBy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.auditing.repository;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.neo4j.auditing.domain.User;
|
||||
import org.springframework.data.neo4j.auditing.domain.UserCustomIdStrategy;
|
||||
import org.springframework.data.neo4j.repository.Neo4jRepository;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
public interface UserCustomIdStrategyRepository extends Neo4jRepository<UserCustomIdStrategy, UUID> {}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.neo4j.ogm.metadata.MetaData;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.AssignedWithPrimitiveVersion;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.AssignedWithVersion;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.AssignedWithoutVersion;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.ExternallyGeneratedNonPrimitive;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.ExternallyGeneratedPrimitive;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.InternallyGeneratedNonPrimitive;
|
||||
import org.springframework.data.neo4j.mapping.datagraph1212.InternallyGeneratedPrimitive;
|
||||
import org.springframework.data.support.IsNewStrategy;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class DefaultNeo4jIsNewStrategyTests {
|
||||
|
||||
MetaData metaData = new MetaData("org.springframework.data.neo4j.mapping.datagraph1212");
|
||||
|
||||
Neo4jMappingContext mappingContext = new Neo4jMappingContext(metaData);
|
||||
|
||||
@Test
|
||||
public void shouldDealWithNonPrimitiveInternalIds() {
|
||||
InternallyGeneratedNonPrimitive a = new InternallyGeneratedNonPrimitive(null);
|
||||
InternallyGeneratedNonPrimitive b = new InternallyGeneratedNonPrimitive(1L);
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(mappingContext.getPersistentEntity(InternallyGeneratedNonPrimitive.class), metaData);
|
||||
assertThat(strategy.isNew(a)).isTrue();
|
||||
assertThat(strategy.isNew(b)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDealWithPrimitiveInternalIds() {
|
||||
InternallyGeneratedPrimitive a = new InternallyGeneratedPrimitive(-1L);
|
||||
InternallyGeneratedPrimitive b = new InternallyGeneratedPrimitive(0L);
|
||||
InternallyGeneratedPrimitive c = new InternallyGeneratedPrimitive(1L);
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(mappingContext.getPersistentEntity(InternallyGeneratedPrimitive.class), metaData);
|
||||
assertThat(strategy.isNew(a)).isTrue();
|
||||
assertThat(strategy.isNew(b)).isFalse();
|
||||
assertThat(strategy.isNew(c)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDealWithNonPrimitiveExternalIds() {
|
||||
ExternallyGeneratedNonPrimitive a = new ExternallyGeneratedNonPrimitive(null);
|
||||
ExternallyGeneratedNonPrimitive b = new ExternallyGeneratedNonPrimitive(UUID.randomUUID());
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(mappingContext.getPersistentEntity(ExternallyGeneratedNonPrimitive.class), metaData);
|
||||
assertThat(strategy.isNew(a)).isTrue();
|
||||
assertThat(strategy.isNew(b)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntNeedToDealWithPrimitiveExternalIds() {
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> DefaultNeo4jIsNewStrategy
|
||||
.basedOn(mappingContext.getPersistentEntity(ExternallyGeneratedPrimitive.class), metaData))
|
||||
.withMessage(
|
||||
"Cannot use org.springframework.data.neo4j.mapping.DefaultNeo4jIsNewStrategy with externally generated, primitive ids.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAlwaysTreatEntitiesAsNewWithoutVersionAndAssignedIds() {
|
||||
|
||||
Neo4jMappingContext context = new Neo4jMappingContext(metaData);
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(context.getPersistentEntity(AssignedWithoutVersion.class), metaData);
|
||||
assertThat(strategy.isNew(new AssignedWithoutVersion())).isTrue();
|
||||
assertThat(strategy.isNew(new AssignedWithoutVersion("someId"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDealWithVersionAndAssignedIds() {
|
||||
|
||||
AssignedWithVersion a = new AssignedWithVersion();
|
||||
AssignedWithVersion b = new AssignedWithVersion("someId");
|
||||
AssignedWithVersion c = new AssignedWithVersion("someId", 1);
|
||||
|
||||
Neo4jMappingContext context = new Neo4jMappingContext(metaData);
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(context.getPersistentEntity(AssignedWithVersion.class), metaData);
|
||||
|
||||
assertThat(strategy.isNew(a)).isTrue();
|
||||
assertThat(strategy.isNew(b)).isTrue();
|
||||
assertThat(strategy.isNew(c)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDealWithPrimitiveVersionAndAssignedIds() {
|
||||
AssignedWithPrimitiveVersion a = new AssignedWithPrimitiveVersion();
|
||||
AssignedWithPrimitiveVersion b = new AssignedWithPrimitiveVersion("someId");
|
||||
AssignedWithPrimitiveVersion c = new AssignedWithPrimitiveVersion("someId", 1);
|
||||
|
||||
Neo4jMappingContext context = new Neo4jMappingContext(metaData);
|
||||
|
||||
IsNewStrategy strategy = DefaultNeo4jIsNewStrategy
|
||||
.basedOn(context.getPersistentEntity(AssignedWithPrimitiveVersion.class), metaData);
|
||||
|
||||
assertThat(strategy.isNew(a)).isTrue();
|
||||
assertThat(strategy.isNew(b)).isTrue();
|
||||
assertThat(strategy.isNew(c)).isFalse();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.Version;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class AssignedWithPrimitiveVersion {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Version
|
||||
private int version;
|
||||
|
||||
public AssignedWithPrimitiveVersion() {
|
||||
}
|
||||
|
||||
public AssignedWithPrimitiveVersion(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AssignedWithPrimitiveVersion(String id, int version) {
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.Version;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class AssignedWithVersion {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Version
|
||||
private Integer version;
|
||||
|
||||
public AssignedWithVersion() {
|
||||
}
|
||||
|
||||
public AssignedWithVersion(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AssignedWithVersion(String id, Integer version) {
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class AssignedWithoutVersion {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
public AssignedWithoutVersion() {
|
||||
}
|
||||
|
||||
public AssignedWithoutVersion(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.typeconversion.Convert;
|
||||
import org.neo4j.ogm.id.UuidStrategy;
|
||||
import org.neo4j.ogm.typeconversion.UuidStringConverter;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class ExternallyGeneratedNonPrimitive {
|
||||
|
||||
@Id @GeneratedValue(strategy = UuidStrategy.class) @Convert(UuidStringConverter.class)
|
||||
private UUID id;
|
||||
|
||||
public ExternallyGeneratedNonPrimitive(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class ExternallyGeneratedPrimitive {
|
||||
|
||||
@Id @GeneratedValue(strategy = WeAllAreFloatingStrategy.class)
|
||||
private float id;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class InternallyGeneratedNonPrimitive {
|
||||
|
||||
@Id @GeneratedValue
|
||||
private Long id;
|
||||
|
||||
public InternallyGeneratedNonPrimitive(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public class InternallyGeneratedPrimitive {
|
||||
|
||||
@Id @GeneratedValue
|
||||
private long id;
|
||||
|
||||
public InternallyGeneratedPrimitive(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2011-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.neo4j.mapping.datagraph1212;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.neo4j.ogm.id.IdStrategy;
|
||||
|
||||
/**
|
||||
* <strong>Don't use this at home!</strong>
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @soundtrack Metallica - Helping Hands… Live & Acoustic At The Masonic
|
||||
*/
|
||||
public final class WeAllAreFloatingStrategy implements IdStrategy {
|
||||
|
||||
@Override
|
||||
public Object generateId(Object entity) {
|
||||
return ThreadLocalRandom.current().nextFloat();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user