fix: Update relationship properties objects before populating result entities.
Closes #2904
This commit is contained in:
@@ -179,6 +179,9 @@ public final class MappingSupport {
|
||||
PersistentPropertyAccessor<Object> relationshipPropertiesAccessor = persistentEntity.getPropertyAccessor(relationshipPropertiesValue);
|
||||
relationshipPropertiesAccessor.setProperty(persistentEntity.getPersistentProperty(TargetNode.class), newRelationshipObject);
|
||||
newRelationshipObject = relationshipPropertiesAccessor.getBean();
|
||||
|
||||
// If we recreate or manipulate the object including it's accessor, we must update it in the holder as well.
|
||||
entityHolder.setRelationshipProperties(newRelationshipObject);
|
||||
}
|
||||
return newRelationshipObject;
|
||||
}
|
||||
@@ -190,14 +193,17 @@ public final class MappingSupport {
|
||||
*/
|
||||
@API(status = API.Status.INTERNAL)
|
||||
public final static class RelationshipPropertiesWithEntityHolder {
|
||||
private final PersistentPropertyAccessor<?> relationshipPropertiesPropertyAccessor;
|
||||
private final Object relationshipProperties;
|
||||
|
||||
private final Neo4jPersistentEntity<?> relationshipPropertiesEntity;
|
||||
private PersistentPropertyAccessor<?> relationshipPropertiesPropertyAccessor;
|
||||
private Object relationshipProperties;
|
||||
private final Object relatedEntity;
|
||||
|
||||
RelationshipPropertiesWithEntityHolder(
|
||||
Neo4jPersistentEntity<?> relationshipPropertiesEntity,
|
||||
Object relationshipProperties, Object relatedEntity
|
||||
) {
|
||||
this.relationshipPropertiesEntity = relationshipPropertiesEntity;
|
||||
this.relationshipPropertiesPropertyAccessor = relationshipPropertiesEntity.getPropertyAccessor(relationshipProperties);
|
||||
this.relationshipProperties = relationshipProperties;
|
||||
this.relatedEntity = relatedEntity;
|
||||
@@ -211,6 +217,11 @@ public final class MappingSupport {
|
||||
return relationshipProperties;
|
||||
}
|
||||
|
||||
private void setRelationshipProperties(Object relationshipProperties) {
|
||||
this.relationshipProperties = relationshipProperties;
|
||||
this.relationshipPropertiesPropertyAccessor = relationshipPropertiesEntity.getPropertyAccessor(this.relationshipProperties);
|
||||
}
|
||||
|
||||
public Object getRelatedEntity() {
|
||||
return relatedEntity;
|
||||
}
|
||||
@@ -231,5 +242,12 @@ public final class MappingSupport {
|
||||
public int hashCode() {
|
||||
return Objects.hash(relationshipProperties, relatedEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RelationshipPropertiesWithEntityHolder{" +
|
||||
"relationshipProperties=" + relationshipProperties +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class MovieEntity {
|
||||
|
||||
// tag::mapping.relationship.properties[]
|
||||
@Relationship(type = "ACTED_IN", direction = Direction.INCOMING) // <.>
|
||||
private List<Roles> actorsAndRoles;
|
||||
private List<Roles> actorsAndRoles = new ArrayList<>();
|
||||
// end::mapping.relationship.properties[]
|
||||
|
||||
@Relationship(type = "DIRECTED", direction = Direction.INCOMING)
|
||||
|
||||
@@ -41,8 +41,21 @@ public class Roles {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
// end::mapping.relationship.properties[]
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
// tag::mapping.relationship.properties[]
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Roles{" +
|
||||
"id=" + id +
|
||||
'}' + this.hashCode();
|
||||
}
|
||||
}
|
||||
// end::mapping.relationship.properties[]
|
||||
|
||||
@@ -23,24 +23,59 @@ import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
// end::faq.template-imperative-pt1[]
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
// tag::faq.template-imperative-pt1[]
|
||||
import org.junit.jupiter.api.Test;
|
||||
// end::faq.template-imperative-pt1[]
|
||||
import org.neo4j.driver.Driver;
|
||||
// tag::faq.template-imperative-pt1[]
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
// end::faq.template-imperative-pt1[]
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
|
||||
// tag::faq.template-imperative-pt1[]
|
||||
import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
// end::faq.template-imperative-pt1[]
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
// tag::faq.template-imperative-pt1[]
|
||||
import org.springframework.data.neo4j.documentation.domain.MovieEntity;
|
||||
import org.springframework.data.neo4j.documentation.domain.PersonEntity;
|
||||
import org.springframework.data.neo4j.documentation.domain.Roles;
|
||||
// end::faq.template-imperative-pt1[]
|
||||
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
|
||||
import org.springframework.data.neo4j.test.BookmarkCapture;
|
||||
import org.springframework.data.neo4j.test.Neo4jExtension;
|
||||
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
|
||||
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
// tag::faq.template-imperative-pt1[]
|
||||
|
||||
// end::faq.template-imperative-pt1[]
|
||||
|
||||
/**
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Disabled
|
||||
@Neo4jIntegrationTest
|
||||
// tag::faq.template-imperative-pt2[]
|
||||
public class TemplateExampleTest {
|
||||
|
||||
// end::faq.template-imperative-pt2[]
|
||||
|
||||
protected static Neo4jExtension.Neo4jConnectionSupport neo4jConnectionSupport;
|
||||
|
||||
@BeforeEach
|
||||
void setup(@Autowired Driver driver, @Autowired BookmarkCapture bookmarkCapture) {
|
||||
try (var session = driver.session(bookmarkCapture.createSessionConfig()); var transaction = session.beginTransaction()) {
|
||||
transaction.run("MATCH (n) detach delete n").consume();
|
||||
transaction.commit();
|
||||
bookmarkCapture.seedWith(session.lastBookmarks());
|
||||
}
|
||||
}
|
||||
|
||||
// tag::faq.template-imperative-pt2[]
|
||||
@Test
|
||||
void shouldSaveAndReadEntities(@Autowired Neo4jTemplate neo4jTemplate) {
|
||||
|
||||
@@ -53,12 +88,45 @@ public class TemplateExampleTest {
|
||||
movie.getActorsAndRoles().add(roles1);
|
||||
movie.getActorsAndRoles().add(roles2);
|
||||
|
||||
neo4jTemplate.save(movie);
|
||||
MovieEntity result = neo4jTemplate.save(movie);
|
||||
// end::mapping.relationship.properties[]
|
||||
assertThat(result.getActorsAndRoles()).allSatisfy(relationship -> assertThat(relationship.getId()).isNotNull());
|
||||
// tag::mapping.relationship.properties[]
|
||||
|
||||
Optional<PersonEntity> person = neo4jTemplate.findById("Dean Jones", PersonEntity.class);
|
||||
assertThat(person).map(PersonEntity::getBorn).hasValue(1931);
|
||||
|
||||
assertThat(neo4jTemplate.count(PersonEntity.class)).isEqualTo(2L);
|
||||
}
|
||||
|
||||
// end::faq.template-imperative-pt2[]
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@EnableNeo4jRepositories(considerNestedRepositories = true)
|
||||
static class Config extends Neo4jImperativeTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public Driver driver() {
|
||||
return neo4jConnectionSupport.getDriver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BookmarkCapture bookmarkCapture() {
|
||||
return new BookmarkCapture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider) {
|
||||
|
||||
BookmarkCapture bookmarkCapture = bookmarkCapture();
|
||||
return new Neo4jTransactionManager(driver, databaseNameProvider, Neo4jBookmarkManager.create(bookmarkCapture));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCypher5Compatible() {
|
||||
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
|
||||
}
|
||||
}
|
||||
// tag::faq.template-imperative-pt2[]
|
||||
}
|
||||
// end::faq.template-imperative-pt2[]
|
||||
|
||||
Reference in New Issue
Block a user