26
26
27
27
import org .apache .commons .logging .Log ;
28
28
import org .apache .commons .logging .LogFactory ;
29
+
29
30
import org .springframework .asm .ClassWriter ;
30
31
import org .springframework .asm .MethodVisitor ;
31
32
import org .springframework .asm .Opcodes ;
32
33
import org .springframework .asm .Type ;
34
+ import org .springframework .beans .BeanInstantiationException ;
33
35
import org .springframework .cglib .core .ReflectUtils ;
34
36
import org .springframework .core .NativeDetector ;
35
37
import org .springframework .data .mapping .PersistentEntity ;
@@ -121,6 +123,10 @@ private EntityInstantiator createEntityInstantiator(PersistentEntity<?, ?> entit
121
123
return ReflectionEntityInstantiator .INSTANCE ;
122
124
}
123
125
126
+ if (Modifier .isAbstract (entity .getType ().getModifiers ())) {
127
+ return MappingInstantiationExceptionEntityInstantiator .create (entity .getType ());
128
+ }
129
+
124
130
try {
125
131
return doCreateEntityInstantiator (entity );
126
132
} catch (Throwable ex ) {
@@ -240,30 +246,30 @@ public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentPrope
240
246
throw new MappingInstantiationException (entity , Arrays .asList (params ), e );
241
247
}
242
248
}
249
+ }
243
250
244
- /**
245
- * Extracts the arguments required to invoke the given constructor from the given {@link ParameterValueProvider}.
246
- *
247
- * @param constructor can be {@literal null}.
248
- * @param provider can be {@literal null}.
249
- * @return
250
- */
251
- private <P extends PersistentProperty <P >, T > Object [] extractInvocationArguments (
252
- @ Nullable PreferredConstructor <? extends T , P > constructor , ParameterValueProvider <P > provider ) {
253
-
254
- if (constructor == null || !constructor .hasParameters ()) {
255
- return allocateArguments (0 );
256
- }
251
+ /**
252
+ * Extracts the arguments required to invoke the given constructor from the given {@link ParameterValueProvider}.
253
+ *
254
+ * @param constructor can be {@literal null}.
255
+ * @param provider can be {@literal null}.
256
+ * @return
257
+ */
258
+ static <P extends PersistentProperty <P >, T > Object [] extractInvocationArguments (
259
+ @ Nullable PreferredConstructor <? extends T , P > constructor , ParameterValueProvider <P > provider ) {
257
260
258
- Object [] params = allocateArguments (constructor .getConstructor ().getParameterCount ());
261
+ if (constructor == null || !constructor .hasParameters ()) {
262
+ return allocateArguments (0 );
263
+ }
259
264
260
- int index = 0 ;
261
- for (Parameter <?, P > parameter : constructor .getParameters ()) {
262
- params [index ++] = provider .getParameterValue (parameter );
263
- }
265
+ Object [] params = allocateArguments (constructor .getConstructor ().getParameterCount ());
264
266
265
- return params ;
267
+ int index = 0 ;
268
+ for (Parameter <?, P > parameter : constructor .getParameters ()) {
269
+ params [index ++] = provider .getParameterValue (parameter );
266
270
}
271
+
272
+ return params ;
267
273
}
268
274
269
275
/**
@@ -276,6 +282,40 @@ public interface ObjectInstantiator {
276
282
Object newInstance (Object ... args );
277
283
}
278
284
285
+ /**
286
+ * {@link EntityInstantiator} throwing {@link MappingInstantiationException} upon
287
+ * {@link #createInstance(PersistentEntity, ParameterValueProvider)}.
288
+ *
289
+ * @author Mark Paluch
290
+ * @since 2.5
291
+ */
292
+ static class MappingInstantiationExceptionEntityInstantiator implements EntityInstantiator {
293
+
294
+ private final Class <?> typeToCreate ;
295
+
296
+ private MappingInstantiationExceptionEntityInstantiator (Class <?> typeToCreate ) {
297
+ this .typeToCreate = typeToCreate ;
298
+ }
299
+
300
+ public static EntityInstantiator create (Class <?> typeToCreate ) {
301
+ return new MappingInstantiationExceptionEntityInstantiator (typeToCreate );
302
+ }
303
+
304
+ /*
305
+ * (non-Javadoc)
306
+ * @see org.springframework.data.mapping.model.EntityInstantiator#createInstance(org.springframework.data.mapping.PersistentEntity, org.springframework.data.mapping.model.ParameterValueProvider)
307
+ */
308
+ @ Override
309
+ public <T , E extends PersistentEntity <? extends T , P >, P extends PersistentProperty <P >> T createInstance (E entity ,
310
+ ParameterValueProvider <P > provider ) {
311
+
312
+ Object [] params = extractInvocationArguments (entity .getPersistenceConstructor (), provider );
313
+
314
+ throw new MappingInstantiationException (entity , Arrays .asList (params ),
315
+ new BeanInstantiationException (typeToCreate , "Class is abstract" ));
316
+ }
317
+ }
318
+
279
319
/**
280
320
* Generates a new {@link ObjectInstantiator} class for the given custom class.
281
321
* <p>
0 commit comments