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:
Michael Simons
2020-09-01 12:20:46 +02:00
parent 1b0e74f84d
commit 2cad20f4b7
16 changed files with 742 additions and 36 deletions

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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");
});
}
}

View File

@@ -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;
}
}

View File

@@ -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> {}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}