1919
2020import java .util .Collection ;
2121import java .util .Collections ;
22+ import java .util .Date ;
2223import java .util .HashSet ;
2324import java .util .List ;
2425import java .util .Set ;
4243import org .springframework .data .neo4j .core .DatabaseSelectionProvider ;
4344import org .springframework .data .neo4j .core .Neo4jOperations ;
4445import org .springframework .data .neo4j .core .convert .Neo4jConversions ;
46+ import org .springframework .data .neo4j .core .support .DateLong ;
4547import org .springframework .data .neo4j .core .transaction .Neo4jBookmarkManager ;
4648import org .springframework .data .neo4j .core .transaction .Neo4jTransactionManager ;
4749import org .springframework .data .neo4j .integration .shared .conversion .PersonWithCustomId ;
@@ -90,7 +92,8 @@ void setupData() {
9092 try (Session session = driver .session (bookmarkCapture .createSessionConfig ())) {
9193 session .writeTransaction (transaction -> {
9294 transaction .run ("MATCH (n) detach delete n" ).consume ();
93- transaction .run ("CREATE (:CustomTypes{customType:'XYZ'})" ).consume ();
95+ transaction .run ("CREATE (:CustomTypes{customType:'XYZ', dateAsLong: 1630311077418})" ).consume ();
96+ transaction .run ("CREATE (:CustomTypes{customType:'ABC'})" ).consume ();
9497 return null ;
9598 });
9699 bookmarkCapture .seedWith (session .lastBookmark ());
@@ -124,7 +127,7 @@ void deleteAllByCustomId() {
124127 .limit (2 )
125128 .collect (Collectors .toList ());
126129 try (
127- Session session = driver .session (bookmarkCapture .createSessionConfig ());
130+ Session session = driver .session (bookmarkCapture .createSessionConfig ())
128131 ) {
129132 ids .forEach (id -> session .writeTransaction (createPersonWithCustomId (id )));
130133 bookmarkCapture .seedWith (session .lastBookmark ());
@@ -143,7 +146,9 @@ void deleteAllByCustomId() {
143146 @ Test
144147 void findByConvertedCustomType (@ Autowired EntityWithCustomTypePropertyRepository repository ) {
145148
146- assertThat (repository .findByCustomType (ThingWithCustomTypes .CustomType .of ("XYZ" ))).isNotNull ();
149+ ThingWithCustomTypes xyz = repository .findByCustomType (ThingWithCustomTypes .CustomType .of ("XYZ" ));
150+ assertThat (xyz ).isNotNull ();
151+ assertThat (xyz .getDateAsLong ()).isNotNull ();
147152 }
148153
149154 @ Test
@@ -152,6 +157,31 @@ void findByConvertedCustomTypeWithCustomQuery(@Autowired EntityWithCustomTypePro
152157 assertThat (repository .findByCustomTypeCustomQuery (ThingWithCustomTypes .CustomType .of ("XYZ" ))).isNotNull ();
153158 }
154159
160+ @ Test // GH-2365
161+ void customConverterShouldBeApplied (@ Autowired EntityWithCustomTypePropertyRepository repository ) {
162+
163+ ThingWithCustomTypes xyz = repository .defaultAttributeWithCoalesce (ThingWithCustomTypes .CustomType .of ("XYZ" ));
164+ assertThat (xyz ).isNotNull ();
165+ assertThat (xyz .getDateAsLong ()).isInSameDayAs ("2021-08-30" );
166+ }
167+
168+ @ Test // GH-2365
169+ void customConverterShouldBeAppliedWithCoalesce (@ Autowired EntityWithCustomTypePropertyRepository repository ) {
170+
171+ ThingWithCustomTypes abc = repository .defaultAttributeWithCoalesce (ThingWithCustomTypes .CustomType .of ("ABC" ));
172+ assertThat (abc ).isNotNull ();
173+ assertThat (abc .getDateAsLong ()).isInSameDayAs ("2021-09-21" );
174+ }
175+
176+ @ Test // GH-2365
177+ void converterAndProjection (@ Autowired EntityWithCustomTypePropertyRepository repository ) {
178+
179+ ThingWithCustomTypesProjection projection = repository .converterOnProjection (ThingWithCustomTypes .CustomType .of ("XYZ" ));
180+ assertThat (projection ).isNotNull ();
181+ assertThat (projection .dateAsLong ).isInSameDayAs ("2021-08-30" );
182+ assertThat (projection .modified ).isInSameDayAs ("2021-09-21" );
183+ }
184+
155185 @ Test
156186 void findByConvertedCustomTypeWithSpELPropertyAccessQuery (
157187 @ Autowired EntityWithCustomTypePropertyRepository repository ) {
@@ -172,13 +202,27 @@ void findByConvertedDifferentTypeWithSpELObjectQuery(@Autowired EntityWithCustom
172202 assertThat (repository .findByDifferentTypeCustomQuery (ThingWithCustomTypes .DifferentType .of ("XYZ" ))).isNotNull ();
173203 }
174204
205+ static class ThingWithCustomTypesProjection {
206+
207+ Date dateAsLong ;
208+
209+ @ DateLong
210+ Date modified ;
211+ }
212+
175213 interface EntityWithCustomTypePropertyRepository extends Neo4jRepository <ThingWithCustomTypes , Long > {
176214
177215 ThingWithCustomTypes findByCustomType (ThingWithCustomTypes .CustomType customType );
178216
179217 @ Query ("MATCH (c:CustomTypes) WHERE c.customType = $customType return c" )
180218 ThingWithCustomTypes findByCustomTypeCustomQuery (@ Param ("customType" ) ThingWithCustomTypes .CustomType customType );
181219
220+ @ Query ("MATCH (c:CustomTypes) WHERE c.customType = $customType return c, 1632200400000 as modified" )
221+ ThingWithCustomTypesProjection converterOnProjection (@ Param ("customType" ) ThingWithCustomTypes .CustomType customType );
222+
223+ @ Query ("MATCH (thingWithCustomTypes:`CustomTypes`) WHERE thingWithCustomTypes.customType = $0 RETURN thingWithCustomTypes{.customType, dateAsLong: COALESCE(thingWithCustomTypes.dateAsLong, 1632200400000), .dateAsString, .id, __nodeLabels__: labels(thingWithCustomTypes), __internalNeo4jId__: id(thingWithCustomTypes)}" )
224+ ThingWithCustomTypes defaultAttributeWithCoalesce (@ Param ("customType" ) ThingWithCustomTypes .CustomType customType );
225+
182226 @ Query ("MATCH (c:CustomTypes) WHERE c.customType = $differentType return c" )
183227 ThingWithCustomTypes findByDifferentTypeCustomQuery (
184228 @ Param ("differentType" ) ThingWithCustomTypes .DifferentType differentType );
0 commit comments