Skip to content

Commit c92fbe4

Browse files
GH-2578 - Document unwinding and pipelining of mapped __properties__.
Closes #2579.
1 parent e77c6e1 commit c92fbe4

File tree

5 files changed

+301
-0
lines changed

5 files changed

+301
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2011-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2579;
17+
18+
import lombok.Data;
19+
20+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
21+
import org.springframework.data.neo4j.core.schema.Id;
22+
import org.springframework.data.neo4j.core.schema.Node;
23+
24+
/**
25+
* @author Michael J. Simons
26+
*/
27+
@Data
28+
@Node("Column")
29+
public class ColumnNode {
30+
31+
@Id
32+
@GeneratedValue
33+
private Long id;
34+
35+
private String sourceName;
36+
37+
private String schemaName;
38+
39+
private String tableName;
40+
41+
private String name;
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright 2011-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2579;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import java.util.Arrays;
21+
import java.util.Collection;
22+
import java.util.Collections;
23+
import java.util.Optional;
24+
25+
import org.junit.jupiter.api.BeforeEach;
26+
import org.junit.jupiter.api.Tag;
27+
import org.junit.jupiter.api.Test;
28+
import org.neo4j.driver.Driver;
29+
import org.neo4j.driver.Session;
30+
import org.springframework.beans.factory.annotation.Autowired;
31+
import org.springframework.context.annotation.Bean;
32+
import org.springframework.context.annotation.Configuration;
33+
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
34+
import org.springframework.data.neo4j.core.Neo4jTemplate;
35+
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
36+
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
37+
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
38+
import org.springframework.data.neo4j.test.BookmarkCapture;
39+
import org.springframework.data.neo4j.test.Neo4jExtension;
40+
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
41+
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
42+
import org.springframework.transaction.PlatformTransactionManager;
43+
import org.springframework.transaction.annotation.EnableTransactionManagement;
44+
45+
/**
46+
* @author Michael J. Simons
47+
*/
48+
@Neo4jIntegrationTest
49+
class GH2579IT {
50+
51+
protected static Neo4jExtension.Neo4jConnectionSupport neo4jConnectionSupport;
52+
53+
@BeforeEach
54+
void setupData(@Autowired Driver driver, @Autowired BookmarkCapture bookmarkCapture) {
55+
56+
try (Session session = driver.session()) {
57+
session.run("MATCH (n) DETACH DELETE n").consume();
58+
bookmarkCapture.seedWith(session.lastBookmark());
59+
}
60+
}
61+
62+
@Test
63+
@Tag("GH-2579")
64+
void unwindWithMergeShouldWork(@Autowired Neo4jTemplate template, @Autowired TableRepository tableRepository) {
65+
66+
TableNode tableNode = new TableNode();
67+
tableNode.setName("t1");
68+
tableNode.setSchemaName("a");
69+
tableNode.setSourceName("source1");
70+
tableNode = template.save(tableNode);
71+
72+
ColumnNode c1 = new ColumnNode();
73+
c1.setName("c1");
74+
c1.setSchemaName("a");
75+
c1.setSourceName("source1");
76+
c1.setTableName(tableNode.getName());
77+
long c1Id = template.save(c1).getId();
78+
79+
ColumnNode c2 = new ColumnNode();
80+
c2.setName("c2");
81+
c2.setSchemaName("a");
82+
c2.setSourceName("source2");
83+
c2.setTableName(tableNode.getName());
84+
long c2Id = template.save(c2).getId();
85+
86+
tableRepository.mergeTableAndColumnRelations(Arrays.asList(c1, c2), tableNode);
87+
88+
Optional<TableNode> resolvedTableNode = tableRepository.findById(tableNode.getId());
89+
assertThat(resolvedTableNode)
90+
.map(TableNode::getTableAndColumnRelation)
91+
.hasValueSatisfying(l -> {
92+
assertThat(l)
93+
.map(TableAndColumnRelation::getColumnNode)
94+
.map(ColumnNode::getId)
95+
.containsExactlyInAnyOrder(c1Id, c2Id);
96+
});
97+
}
98+
99+
@Configuration
100+
@EnableTransactionManagement
101+
@EnableNeo4jRepositories(considerNestedRepositories = true)
102+
static class Config extends Neo4jImperativeTestConfiguration {
103+
104+
@Bean
105+
public BookmarkCapture bookmarkCapture() {
106+
return new BookmarkCapture();
107+
}
108+
109+
@Override
110+
public PlatformTransactionManager transactionManager(
111+
Driver driver, DatabaseSelectionProvider databaseNameProvider) {
112+
113+
BookmarkCapture bookmarkCapture = bookmarkCapture();
114+
return new Neo4jTransactionManager(driver, databaseNameProvider,
115+
Neo4jBookmarkManager.create(bookmarkCapture));
116+
}
117+
118+
@Override
119+
protected Collection<String> getMappingBasePackages() {
120+
return Collections.singleton(TableNode.class.getPackage().getName());
121+
}
122+
123+
@Bean
124+
public Driver driver() {
125+
126+
return neo4jConnectionSupport.getDriver();
127+
}
128+
129+
@Override
130+
public boolean isCypher5Compatible() {
131+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
132+
}
133+
}
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2011-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2579;
17+
18+
import lombok.Data;
19+
20+
import org.springframework.data.neo4j.core.schema.RelationshipId;
21+
import org.springframework.data.neo4j.core.schema.RelationshipProperties;
22+
import org.springframework.data.neo4j.core.schema.TargetNode;
23+
24+
/**
25+
* @author Michael J. Simons
26+
*/
27+
@Data
28+
@RelationshipProperties
29+
public class TableAndColumnRelation {
30+
31+
@RelationshipId
32+
private Long id;
33+
34+
@TargetNode
35+
private ColumnNode columnNode;
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2011-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2579;
17+
18+
import lombok.Data;
19+
20+
import java.util.List;
21+
22+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
23+
import org.springframework.data.neo4j.core.schema.Id;
24+
import org.springframework.data.neo4j.core.schema.Node;
25+
import org.springframework.data.neo4j.core.schema.Relationship;
26+
27+
/**
28+
* @author Michael J. Simons
29+
*/
30+
@Data
31+
@Node("Table")
32+
public class TableNode {
33+
34+
@Id
35+
@GeneratedValue
36+
private Long id;
37+
38+
private String sourceName;
39+
40+
private String schemaName;
41+
42+
private String name;
43+
44+
private String tableComment;
45+
46+
@Relationship(type = "BELONG", direction = Relationship.Direction.INCOMING)
47+
private List<TableAndColumnRelation> tableAndColumnRelation;
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2011-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2579;
17+
18+
import java.util.List;
19+
20+
import org.springframework.data.neo4j.repository.Neo4jRepository;
21+
import org.springframework.data.neo4j.repository.query.Query;
22+
import org.springframework.data.repository.query.Param;
23+
24+
/**
25+
* @author Michael J. Simons
26+
*/
27+
public interface TableRepository extends Neo4jRepository<TableNode, Long> {
28+
29+
@Query(value =
30+
"UNWIND :#{#froms} AS col " +
31+
"WITH col.__properties__ AS col, :#{#to}.__properties__ AS to " +
32+
"MERGE (c:Column { sourceName : col.sourceName, " +
33+
"schemaName : col.schemaName, " +
34+
"tableName : col.tableName, " +
35+
"name : col.name }) " +
36+
"MERGE (t:Table {sourceName : to.sourceName, " +
37+
"schemaName : to.schemaName, " +
38+
"name : to.name }) " +
39+
"MERGE (c) -[r:BELONG]-> (t) ")
40+
void mergeTableAndColumnRelations(@Param("froms") List<ColumnNode> froms, @Param("to") TableNode to);
41+
}

0 commit comments

Comments
 (0)