2626
2727import org .apache .commons .logging .Log ;
2828import org .apache .commons .logging .LogFactory ;
29+
2930import org .springframework .asm .ClassWriter ;
3031import org .springframework .asm .MethodVisitor ;
3132import org .springframework .asm .Opcodes ;
3233import org .springframework .asm .Type ;
34+ import org .springframework .beans .BeanInstantiationException ;
3335import org .springframework .cglib .core .ReflectUtils ;
3436import org .springframework .core .NativeDetector ;
3537import org .springframework .data .mapping .PersistentEntity ;
@@ -121,6 +123,10 @@ private EntityInstantiator createEntityInstantiator(PersistentEntity<?, ?> entit
121123 return ReflectionEntityInstantiator .INSTANCE ;
122124 }
123125
126+ if (Modifier .isAbstract (entity .getType ().getModifiers ())) {
127+ return MappingInstantiationExceptionEntityInstantiator .create (entity .getType ());
128+ }
129+
124130 try {
125131 return doCreateEntityInstantiator (entity );
126132 } catch (Throwable ex ) {
@@ -240,30 +246,30 @@ public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentPrope
240246 throw new MappingInstantiationException (entity , Arrays .asList (params ), e );
241247 }
242248 }
249+ }
243250
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 ) {
257260
258- Object [] params = allocateArguments (constructor .getConstructor ().getParameterCount ());
261+ if (constructor == null || !constructor .hasParameters ()) {
262+ return allocateArguments (0 );
263+ }
259264
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 ());
264266
265- return params ;
267+ int index = 0 ;
268+ for (Parameter <?, P > parameter : constructor .getParameters ()) {
269+ params [index ++] = provider .getParameterValue (parameter );
266270 }
271+
272+ return params ;
267273 }
268274
269275 /**
@@ -276,6 +282,40 @@ public interface ObjectInstantiator {
276282 Object newInstance (Object ... args );
277283 }
278284
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+
279319 /**
280320 * Generates a new {@link ObjectInstantiator} class for the given custom class.
281321 * <p>
0 commit comments