Skip to content

Commit 501e003

Browse files
Add converter from java.util.Map to org.neo4j.driver.Value.
Closes #2576.
1 parent cc77019 commit 501e003

File tree

5 files changed

+279
-0
lines changed

5 files changed

+279
-0
lines changed

src/main/java/org/springframework/data/neo4j/core/convert/AdditionalTypes.java

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.HashSet;
3333
import java.util.List;
3434
import java.util.Locale;
35+
import java.util.Map;
3536
import java.util.Set;
3637
import java.util.TimeZone;
3738
import java.util.UUID;
@@ -102,10 +103,15 @@ final class AdditionalTypes {
102103
hlp.add(ConverterBuilder.reading(Value.class, Entity.class, Value::asEntity));
103104
hlp.add(ConverterBuilder.reading(Value.class, Node.class, Value::asNode));
104105
hlp.add(ConverterBuilder.reading(Value.class, Relationship.class, Value::asRelationship));
106+
hlp.add(ConverterBuilder.reading(Value.class, Map.class, Value::asMap).andWriting(AdditionalTypes::value));
105107

106108
CONVERTERS = Collections.unmodifiableList(hlp);
107109
}
108110

111+
static Value value(Map<?, ?> map) {
112+
return Values.value(map);
113+
}
114+
109115
static TimeZone asTimeZone(Value value) {
110116
return TimeZone.getTimeZone(value.asString());
111117
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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.gh2576;
17+
18+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
19+
import org.springframework.data.neo4j.core.schema.Id;
20+
import org.springframework.data.neo4j.core.schema.Node;
21+
import org.springframework.data.neo4j.core.support.UUIDStringGenerator;
22+
23+
/**
24+
* @author Michael J. Simons
25+
*/
26+
@Node
27+
public class College {
28+
29+
@Id @GeneratedValue(UUIDStringGenerator.class)
30+
private String guid;
31+
32+
private String name;
33+
34+
public College(String name) {
35+
this.name = name;
36+
}
37+
38+
public String getGuid() {
39+
return guid;
40+
}
41+
42+
public String getName() {
43+
return name;
44+
}
45+
46+
public void setName(String name) {
47+
this.name = name;
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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.gh2576;
17+
18+
import java.util.List;
19+
import java.util.Map;
20+
21+
import org.neo4j.driver.Value;
22+
import org.springframework.data.neo4j.repository.Neo4jRepository;
23+
import org.springframework.data.neo4j.repository.query.Query;
24+
25+
/**
26+
* @author Michael J. Simons
27+
*/
28+
public interface CollegeRepository extends Neo4jRepository<College, String> {
29+
30+
@Query(""
31+
+ "UNWIND $0 AS row\n"
32+
+ "MATCH (student:Student{guid:row.stuGuid})\n"
33+
+ "MATCH (college:College{guid:row.collegeGuid})\n"
34+
+ "CREATE (student)<-[:STUDENT_OF]-(college) RETURN student.guid"
35+
)
36+
List<String> addStudentToCollege(List<Map<String, String>> list);
37+
38+
@Query(""
39+
+ "UNWIND $0 AS row\n"
40+
+ "MATCH (student:Student{guid:row.stuGuid})\n"
41+
+ "MATCH (college:College{guid:row.collegeGuid})\n"
42+
+ "CREATE (student)<-[:STUDENT_OF]-(college) RETURN student.guid"
43+
)
44+
List<String> addStudentToCollegeWorkaround(List<Value> list);
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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.gh2576;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import java.util.Collection;
21+
import java.util.Collections;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
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.Value;
30+
import org.neo4j.driver.Values;
31+
import org.springframework.beans.factory.annotation.Autowired;
32+
import org.springframework.context.annotation.Bean;
33+
import org.springframework.context.annotation.Configuration;
34+
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
35+
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
36+
import org.springframework.data.neo4j.core.Neo4jTemplate;
37+
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
38+
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
39+
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
40+
import org.springframework.data.neo4j.test.BookmarkCapture;
41+
import org.springframework.data.neo4j.test.Neo4jExtension;
42+
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
43+
import org.springframework.transaction.PlatformTransactionManager;
44+
import org.springframework.transaction.annotation.EnableTransactionManagement;
45+
46+
/**
47+
* @author Michael J. Simons
48+
*/
49+
@Neo4jIntegrationTest
50+
class GH2576IT {
51+
52+
protected static Neo4jExtension.Neo4jConnectionSupport neo4jConnectionSupport;
53+
54+
@Test
55+
@Tag("GH-2576")
56+
void listOfMapsShouldBeUsableAsArguments(@Autowired Neo4jTemplate template,
57+
@Autowired CollegeRepository collegeRepository) {
58+
59+
Student student = template.save(new Student("S1"));
60+
College college = template.save(new College("C1"));
61+
62+
Map<String, String> pair = new HashMap<>();
63+
pair.put("stuGuid", student.getGuid());
64+
pair.put("collegeGuid", college.getGuid());
65+
List<Map<String, String>> listOfPairs = Collections.singletonList(pair);
66+
67+
List<String> uuids = collegeRepository.addStudentToCollege(listOfPairs);
68+
assertThat(uuids).containsExactly(student.getGuid());
69+
}
70+
71+
@Test
72+
@Tag("GH-2576")
73+
void listOfMapsShouldBeUsableAsArgumentsWithWorkaround(@Autowired Neo4jTemplate template,
74+
@Autowired CollegeRepository collegeRepository) {
75+
76+
Student student = template.save(new Student("S1"));
77+
College college = template.save(new College("C1"));
78+
79+
Map<String, String> pair = new HashMap<>();
80+
pair.put("stuGuid", student.getGuid());
81+
pair.put("collegeGuid", college.getGuid());
82+
List<Value> listOfPairs = Collections.singletonList(Values.value(pair));
83+
84+
List<String> uuids = collegeRepository.addStudentToCollegeWorkaround(listOfPairs);
85+
assertThat(uuids).containsExactly(student.getGuid());
86+
}
87+
88+
@Configuration
89+
@EnableTransactionManagement
90+
@EnableNeo4jRepositories(considerNestedRepositories = true)
91+
static class Config extends AbstractNeo4jConfig {
92+
93+
@Bean
94+
public BookmarkCapture bookmarkCapture() {
95+
return new BookmarkCapture();
96+
}
97+
98+
@Override
99+
public PlatformTransactionManager transactionManager(
100+
Driver driver, DatabaseSelectionProvider databaseNameProvider) {
101+
102+
BookmarkCapture bookmarkCapture = bookmarkCapture();
103+
return new Neo4jTransactionManager(driver, databaseNameProvider,
104+
Neo4jBookmarkManager.create(bookmarkCapture));
105+
}
106+
107+
@Override
108+
protected Collection<String> getMappingBasePackages() {
109+
return Collections.singleton(Student.class.getPackage().getName());
110+
}
111+
112+
@Bean
113+
public Driver driver() {
114+
115+
return neo4jConnectionSupport.getDriver();
116+
}
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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.gh2576;
17+
18+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
19+
import org.springframework.data.neo4j.core.schema.Id;
20+
import org.springframework.data.neo4j.core.schema.Node;
21+
import org.springframework.data.neo4j.core.schema.Relationship;
22+
import org.springframework.data.neo4j.core.support.UUIDStringGenerator;
23+
24+
/**
25+
* @author Michael J. Simons
26+
*/
27+
@Node
28+
public class Student {
29+
30+
@Id @GeneratedValue(UUIDStringGenerator.class)
31+
private String guid;
32+
33+
private String name;
34+
35+
@Relationship(type = "STUDENT_OF", direction = Relationship.Direction.OUTGOING)
36+
private College college;
37+
38+
public Student(String name) {
39+
this.name = name;
40+
}
41+
42+
public String getGuid() {
43+
return guid;
44+
}
45+
46+
public String getName() {
47+
return name;
48+
}
49+
50+
public void setName(String name) {
51+
this.name = name;
52+
}
53+
54+
public College getCollege() {
55+
return college;
56+
}
57+
58+
public void setCollege(College college) {
59+
this.college = college;
60+
}
61+
}

0 commit comments

Comments
 (0)