66
66
import org .springframework .data .neo4j .core .schema .IdGenerator ;
67
67
import org .springframework .data .neo4j .core .schema .Node ;
68
68
import org .springframework .data .neo4j .core .schema .PostLoad ;
69
+ import org .springframework .data .util .Lazy ;
69
70
import org .springframework .data .util .TypeInformation ;
70
71
import org .springframework .lang .Nullable ;
71
72
import org .springframework .util .ReflectionUtils ;
@@ -117,26 +118,67 @@ public final class Neo4jMappingContext extends AbstractMappingContext<Neo4jPersi
117
118
118
119
private boolean strict = false ;
119
120
120
- public Neo4jMappingContext () {
121
+ private final Lazy <PersistentPropertyCharacteristicsProvider > propertyCharacteristicsProvider ;
122
+
123
+ /**
124
+ * A builder for creating custom instances of a {@link Neo4jMappingContext}.
125
+ * @since 6.3.7
126
+ */
127
+ public static class Builder {
128
+
129
+ private Neo4jConversions neo4jConversions ;
130
+
131
+ @ Nullable
132
+ private TypeSystem typeSystem ;
121
133
122
- this (new Neo4jConversions ());
134
+ @ Nullable
135
+ private PersistentPropertyCharacteristicsProvider persistentPropertyCharacteristicsProvider ;
136
+
137
+ private Builder () {
138
+ this (new Neo4jConversions (), null , null );
139
+ }
140
+
141
+ private Builder (Neo4jConversions neo4jConversions , @ Nullable TypeSystem typeSystem , @ Nullable PersistentPropertyCharacteristicsProvider persistentPropertyCharacteristicsProvider ) {
142
+ this .neo4jConversions = neo4jConversions ;
143
+ this .typeSystem = typeSystem ;
144
+ this .persistentPropertyCharacteristicsProvider = persistentPropertyCharacteristicsProvider ;
145
+ }
146
+
147
+ @ SuppressWarnings ("HiddenField" )
148
+ public Builder withNeo4jConversions (@ Nullable Neo4jConversions neo4jConversions ) {
149
+ this .neo4jConversions = neo4jConversions ;
150
+ return this ;
151
+ }
152
+
153
+ @ SuppressWarnings ("HiddenField" )
154
+ public Builder withPersistentPropertyCharacteristicsProvider (@ Nullable PersistentPropertyCharacteristicsProvider persistentPropertyCharacteristicsProvider ) {
155
+ this .persistentPropertyCharacteristicsProvider = persistentPropertyCharacteristicsProvider ;
156
+ return this ;
157
+ }
158
+
159
+ @ SuppressWarnings ("HiddenField" )
160
+ public Builder withTypeSystem (@ Nullable TypeSystem typeSystem ) {
161
+ this .typeSystem = typeSystem ;
162
+ return this ;
163
+ }
164
+
165
+ public Neo4jMappingContext build () {
166
+ return new Neo4jMappingContext (this );
167
+ }
123
168
}
124
169
125
- public Neo4jMappingContext (Neo4jConversions neo4jConversions ) {
170
+ public static Builder builder () {
171
+ return new Builder ();
172
+ }
173
+
174
+ public Neo4jMappingContext () {
126
175
127
- this (neo4jConversions , null );
176
+ this (new Builder () );
128
177
}
129
178
130
- /**
131
- * We need to set the context to non-strict in case we must dynamically add parent classes. As there is no
132
- * way to access the original value without reflection, we track its change.
133
- *
134
- * @param strict The new value for the strict setting.
135
- */
136
- @ Override
137
- public void setStrict (boolean strict ) {
138
- super .setStrict (strict );
139
- this .strict = strict ;
179
+ public Neo4jMappingContext (Neo4jConversions neo4jConversions ) {
180
+
181
+ this (new Builder (neo4jConversions , null , null ));
140
182
}
141
183
142
184
/**
@@ -145,17 +187,40 @@ public void setStrict(boolean strict) {
145
187
*
146
188
* @param neo4jConversions The conversions to be used
147
189
* @param typeSystem The current drivers type system. If this is null, we use the default one without accessing the driver.
190
+ * @deprecated Use {@link Neo4jMappingContext#builder()}
148
191
*/
149
192
@ API (status = API .Status .INTERNAL , since = "6.0" )
193
+ @ Deprecated
150
194
public Neo4jMappingContext (Neo4jConversions neo4jConversions , @ Nullable TypeSystem typeSystem ) {
195
+ this (new Builder (neo4jConversions , typeSystem , null ));
196
+ }
197
+
198
+ private Neo4jMappingContext (Builder builder ) {
151
199
152
- this .conversionService = new DefaultNeo4jConversionService (neo4jConversions );
153
- this .typeSystem = typeSystem == null ? InternalTypeSystem .TYPE_SYSTEM : typeSystem ;
200
+ this .conversionService = new DefaultNeo4jConversionService (builder . neo4jConversions );
201
+ this .typeSystem = builder . typeSystem == null ? InternalTypeSystem .TYPE_SYSTEM : builder . typeSystem ;
154
202
this .eventSupport = EventSupport .useExistingCallbacks (this , EntityCallbacks .create ());
155
203
156
- super .setSimpleTypeHolder (neo4jConversions .getSimpleTypeHolder ());
204
+ super .setSimpleTypeHolder (builder .neo4jConversions .getSimpleTypeHolder ());
205
+
206
+ PersistentPropertyCharacteristicsProvider characteristicsProvider = builder .persistentPropertyCharacteristicsProvider ;
207
+ this .propertyCharacteristicsProvider = Lazy .of (() -> characteristicsProvider != null || this .beanFactory == null ?
208
+ characteristicsProvider : this .beanFactory .getBeanProvider (PersistentPropertyCharacteristicsProvider .class ).getIfUnique ());
157
209
}
158
210
211
+ /**
212
+ * We need to set the context to non-strict in case we must dynamically add parent classes. As there is no
213
+ * way to access the original value without reflection, we track its change.
214
+ *
215
+ * @param strict The new value for the strict setting.
216
+ */
217
+ @ Override
218
+ public void setStrict (boolean strict ) {
219
+ super .setStrict (strict );
220
+ this .strict = strict ;
221
+ }
222
+
223
+
159
224
public Neo4jEntityConverter getEntityConverter () {
160
225
return new DefaultNeo4jEntityConverter (INSTANTIATORS , nodeDescriptionStore , conversionService , eventSupport ,
161
226
typeSystem );
@@ -260,7 +325,12 @@ private static boolean isValidParentNode(@Nullable Class<?> parentClass) {
260
325
protected Neo4jPersistentProperty createPersistentProperty (Property property , Neo4jPersistentEntity <?> owner ,
261
326
SimpleTypeHolder simpleTypeHolder ) {
262
327
263
- return new DefaultNeo4jPersistentProperty (property , owner , this , simpleTypeHolder );
328
+ PersistentPropertyCharacteristics optionalCharacteristics = this .propertyCharacteristicsProvider
329
+ .getOptional ()
330
+ .flatMap (provider -> Optional .ofNullable (provider .apply (property , owner )))
331
+ .orElse (null );
332
+
333
+ return new DefaultNeo4jPersistentProperty (property , owner , this , simpleTypeHolder , optionalCharacteristics );
264
334
}
265
335
266
336
@ Override
@@ -278,9 +348,9 @@ public NodeDescription<?> getNodeDescription(Class<?> underlyingClass) {
278
348
@ Nullable
279
349
public Neo4jPersistentEntity <?> getPersistentEntity (TypeInformation <?> typeInformation ) {
280
350
281
- NodeDescription <?> existingDescription = this .doGetPersistentEntity (typeInformation );
351
+ Neo4jPersistentEntity <?> existingDescription = this .doGetPersistentEntity (typeInformation );
282
352
if (existingDescription != null ) {
283
- return ( Neo4jPersistentEntity <?>) existingDescription ;
353
+ return existingDescription ;
284
354
}
285
355
return super .getPersistentEntity (typeInformation );
286
356
}
0 commit comments