From 72fa04d81d6a194fa5df0a000527df47ab4847f7 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Mon, 6 May 2019 11:46:22 +0200 Subject: [PATCH] DATAGRAPH-1220 - Ensure Kotlin Data classes support @Id @Generated value. (#490) --- .../PersistenceConstructorsTests.java | 59 +++++++++++++++++++ .../constructors/domain/KotlinPerson.kt | 12 ++++ 2 files changed, 71 insertions(+) diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/integration/constructors/PersistenceConstructorsTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/integration/constructors/PersistenceConstructorsTests.java index 96b1065c6..8363b499e 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/integration/constructors/PersistenceConstructorsTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/integration/constructors/PersistenceConstructorsTests.java @@ -16,6 +16,7 @@ package org.springframework.data.neo4j.integration.constructors; import static java.util.stream.Collectors.*; +import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import java.util.ArrayList; @@ -24,9 +25,11 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Optional; import java.util.stream.StreamSupport; import org.assertj.core.util.DateUtil; +import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -51,6 +54,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.support.TransactionTemplate; /** * @author Nicolas Mervaillie @@ -82,6 +86,10 @@ public class PersistenceConstructorsTests { @Autowired KotlinPersonRepository kotlinRepository; + @Autowired KotlinDataPersonRepository kotlinDataPersonRepository; + + @Autowired TransactionTemplate transactionTemplate; + @Test public void shouldHandleSimpleEntityWithConstructor() { @@ -209,6 +217,49 @@ public class PersistenceConstructorsTests { assertEquals("foo", persons.iterator().next().getName()); } + @Test // DATAGRAPH-1220 + public void shouldSupportKotlinDataClassesWithGeneratedIds() { + + KotlinDataPerson person0 = KotlinPersonKt.newDataPerson("Not to be persisted"); + + // Make sure we don't interfere with OGMs session cache but also don't clean it externally + + KotlinDataPerson person1 = transactionTemplate + .execute(t -> kotlinDataPersonRepository.save(KotlinPersonKt.newDataPerson("Data Person 1"))); + KotlinDataPerson person2 = transactionTemplate + .execute(t -> kotlinDataPersonRepository.save(KotlinPersonKt.newDataPerson("Data Person 2"))); + + // Assert that the id is actually null without database interaction + assertThat(person0.getId(), is(nullValue())); + assertThat(person1.getId(), is(notNullValue())); + assertThat(person2.getId(), is(notNullValue())); + + // Load the rest + transactionTemplate.execute(t -> { + List loadedPersons = kotlinDataPersonRepository.findAll(); + assertThat(loadedPersons.size(), is(2)); + assertThat(loadedPersons, CoreMatchers.hasItems(person1, person2)); + return null; + }); + + transactionTemplate.execute(t -> { + Optional loadedPerson1 = kotlinDataPersonRepository.findById(person1.getId()); + Optional loadedPerson2 = kotlinDataPersonRepository.findById(person2.getId()); + + assertThat(loadedPerson1.isPresent(), is(true)); + assertThat(loadedPerson2.isPresent(), is(true)); + return null; + }); + + // Double check the finder by another index field + transactionTemplate.execute(t -> { + + Optional loadedPerson1 = kotlinDataPersonRepository.findByName(person1.getName()); + assertThat(loadedPerson1.isPresent(), is(true)); + return null; + }); + } + @Test public void shouldSupportQueryResults() { session.query( @@ -245,6 +296,14 @@ public class PersistenceConstructorsTests { @Repository public interface KotlinPersonRepository extends Neo4jRepository {} + @Repository + public interface KotlinDataPersonRepository extends Neo4jRepository { + + List findAll(); + + Optional findByName(String name); + } + @Repository public interface PersonMultipleConstructorsRepository extends Neo4jRepository {} diff --git a/spring-data-neo4j/src/test/kotlin/org/springframework/data/neo4j/integration/constructors/domain/KotlinPerson.kt b/spring-data-neo4j/src/test/kotlin/org/springframework/data/neo4j/integration/constructors/domain/KotlinPerson.kt index 43013f3d8..4e5eb410b 100644 --- a/spring-data-neo4j/src/test/kotlin/org/springframework/data/neo4j/integration/constructors/domain/KotlinPerson.kt +++ b/spring-data-neo4j/src/test/kotlin/org/springframework/data/neo4j/integration/constructors/domain/KotlinPerson.kt @@ -15,12 +15,15 @@ */ package org.springframework.data.neo4j.integration.constructors.domain +import org.neo4j.ogm.annotation.GeneratedValue import org.neo4j.ogm.annotation.Id +import org.neo4j.ogm.annotation.Index import org.neo4j.ogm.annotation.NodeEntity import org.neo4j.ogm.annotation.Relationship /** * @author Nicolas Mervaillie + * @author Michael J. Simons */ @NodeEntity data class KotlinPerson( @@ -28,3 +31,12 @@ data class KotlinPerson( @Relationship var friendships: List = ArrayList()) { } + +@NodeEntity +data class KotlinDataPerson( + @Id @GeneratedValue var id: Long? = null, + @Index(unique = true) var name: String +) + +// Just a helper to omit the id constructor parameter completely when calling from Java. +fun newDataPerson(name: String) = KotlinDataPerson(name = name)