diff --git a/core/src/main/java/org/neo4j/ogm/context/EntityGraphMapper.java b/core/src/main/java/org/neo4j/ogm/context/EntityGraphMapper.java index 63f67699f..cf0d7cf4f 100644 --- a/core/src/main/java/org/neo4j/ogm/context/EntityGraphMapper.java +++ b/core/src/main/java/org/neo4j/ogm/context/EntityGraphMapper.java @@ -425,7 +425,7 @@ private void mapEntityReferences(final Object entity, NodeBuilder nodeBuilder, i if (isRelationshipEntity(relatedObject)) { ClassInfo declaredObjectInfo = metaData.classInfo(relationshipType); - if (declaredObjectInfo.isAbstract()) { + if (declaredObjectInfo != null && declaredObjectInfo.isAbstract()) { final ClassInfo relatedObjectClassInfo = metaData.classInfo(relatedObject); if (!relatedObjectClassInfo.neo4jName().equals(directedRelationship.type())) { directedRelationship = new DirectedRelationship(relatedObjectClassInfo.neo4jName(), diff --git a/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/EntityGraphMapperTest.java b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/EntityGraphMapperTest.java index 8b01a1f80..b4a446761 100644 --- a/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/EntityGraphMapperTest.java +++ b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/EntityGraphMapperTest.java @@ -39,6 +39,7 @@ import org.neo4j.ogm.context.EntityMapper; import org.neo4j.ogm.context.MappingContext; import org.neo4j.ogm.cypher.compiler.Compiler; +import org.neo4j.ogm.cypher.query.CypherQuery; import org.neo4j.ogm.domain.blog.Post; import org.neo4j.ogm.domain.education.Course; import org.neo4j.ogm.domain.education.School; @@ -58,6 +59,11 @@ import org.neo4j.ogm.persistence.examples.versioned_rel_entity.A; import org.neo4j.ogm.persistence.examples.versioned_rel_entity.B; import org.neo4j.ogm.persistence.examples.versioned_rel_entity.R; +import org.neo4j.ogm.persistence.model.gh1134.RelEntity; +import org.neo4j.ogm.persistence.model.gh1134.NodeWithSomewhatInvalidRelationshipDeclaration; +import org.neo4j.ogm.request.OptimisticLockingConfig; +import org.neo4j.ogm.request.Statement; +import org.neo4j.ogm.request.StatementFactory; import org.neo4j.ogm.request.Statements; import org.neo4j.ogm.session.Session; import org.neo4j.ogm.session.SessionFactory; @@ -943,6 +949,37 @@ void shouldNotMessUpMixedTypedLists() { }); } + @Test + void mappingEntityRefMustCheckForNullRel() { + + mappingMetadata = new MetaData("org.neo4j.ogm.persistence.model.gh1134"); + mappingContext = new MappingContext(mappingMetadata); + + EntityGraphMapper mapper = new EntityGraphMapper(mappingMetadata, mappingContext); + NodeWithSomewhatInvalidRelationshipDeclaration start = new NodeWithSomewhatInvalidRelationshipDeclaration(); + start.setId("s"); + NodeWithSomewhatInvalidRelationshipDeclaration end = new NodeWithSomewhatInvalidRelationshipDeclaration(); + end.setId("e"); + RelEntity rel = new RelEntity(start, end); + start.setRelatedObject(rel); + + Compiler compiler = mapper.map(start).getCompiler(); + compiler.useStatementFactory(new StatementFactory() { + @Override + public Statement statement(String statement, Map parameters) { + return new CypherQuery(statement, parameters); + } + + @Override + public Statement statement(String statement, Map parameters, + OptimisticLockingConfig config) { + return new CypherQuery(statement, parameters); + } + }); + assertThat(compiler.createRelationshipsStatements().stream().map(Statement::getStatement)).first() + .isEqualTo("UNWIND $rows as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId MERGE (startNode)-[rel:`whatever`]->(endNode) RETURN row.relRef as ref, ID(rel) as id, $type as type"); + } + @Test // GH-902 @SuppressWarnings("unchecked") void nestedListsWithDomainModel() { diff --git a/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/NodeWithSomewhatInvalidRelationshipDeclaration.java b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/NodeWithSomewhatInvalidRelationshipDeclaration.java new file mode 100644 index 000000000..43a6fe36d --- /dev/null +++ b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/NodeWithSomewhatInvalidRelationshipDeclaration.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002-2024 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * 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 + * + * http://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.neo4j.ogm.persistence.model.gh1134; + +import org.neo4j.ogm.annotation.Id; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Relationship; + +@NodeEntity +public class NodeWithSomewhatInvalidRelationshipDeclaration { + @Id + private String id; + + @Relationship(type = "whatever") + private RelEntity relatedObject; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public RelEntity getRelatedObject() { + return relatedObject; + } + + public void setRelatedObject(RelEntity relatedObject) { + this.relatedObject = relatedObject; + } +} diff --git a/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/RelEntity.java b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/RelEntity.java new file mode 100644 index 000000000..6de132552 --- /dev/null +++ b/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/persistence/model/gh1134/RelEntity.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2002-2024 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * 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 + * + * http://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.neo4j.ogm.persistence.model.gh1134; + +import org.neo4j.ogm.annotation.EndNode; +import org.neo4j.ogm.annotation.RelationshipEntity; +import org.neo4j.ogm.annotation.StartNode; + +@RelationshipEntity +public class RelEntity { + + public Long id; + + @StartNode + private NodeWithSomewhatInvalidRelationshipDeclaration start; + + @EndNode + private NodeWithSomewhatInvalidRelationshipDeclaration end; + + public RelEntity( + NodeWithSomewhatInvalidRelationshipDeclaration start, NodeWithSomewhatInvalidRelationshipDeclaration end) { + this.end = end; + this.start = start; + } +}