|
64 | 64 | import org.springframework.data.mapping.model.SimpleTypeHolder; |
65 | 65 | import org.springframework.data.spel.EvaluationContextProvider; |
66 | 66 | import org.springframework.data.spel.ExtensionAwareEvaluationContextProvider; |
| 67 | +import org.springframework.data.util.CustomCollections; |
67 | 68 | import org.springframework.data.util.KotlinReflectionUtils; |
68 | 69 | import org.springframework.data.util.NullableWrapperConverters; |
69 | 70 | import org.springframework.data.util.Optionals; |
@@ -458,16 +459,18 @@ private E doAddPersistentEntity(TypeInformation<?> typeInformation) { |
458 | 459 | persistentEntities.put(typeInformation, Optional.of(entity)); |
459 | 460 | } |
460 | 461 |
|
461 | | - PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(type); |
462 | | - Map<String, PropertyDescriptor> descriptors = new HashMap<>(); |
| 462 | + if (shouldCreateProperties(userTypeInformation)) { |
| 463 | + PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(type); |
| 464 | + Map<String, PropertyDescriptor> descriptors = new HashMap<>(); |
463 | 465 |
|
464 | | - for (PropertyDescriptor descriptor : pds) { |
465 | | - descriptors.put(descriptor.getName(), descriptor); |
466 | | - } |
| 466 | + for (PropertyDescriptor descriptor : pds) { |
| 467 | + descriptors.put(descriptor.getName(), descriptor); |
| 468 | + } |
467 | 469 |
|
468 | | - PersistentPropertyCreator persistentPropertyCreator = new PersistentPropertyCreator(entity, descriptors); |
469 | | - ReflectionUtils.doWithFields(type, persistentPropertyCreator, PersistentPropertyFilter.INSTANCE); |
470 | | - persistentPropertyCreator.addPropertiesForRemainingDescriptors(); |
| 470 | + PersistentPropertyCreator persistentPropertyCreator = new PersistentPropertyCreator(entity, descriptors); |
| 471 | + ReflectionUtils.doWithFields(type, persistentPropertyCreator, PersistentPropertyFilter.INSTANCE); |
| 472 | + persistentPropertyCreator.addPropertiesForRemainingDescriptors(); |
| 473 | + } |
471 | 474 |
|
472 | 475 | entity.verify(); |
473 | 476 |
|
@@ -518,6 +521,35 @@ public Collection<TypeInformation<?>> getManagedTypes() { |
518 | 521 | */ |
519 | 522 | protected abstract P createPersistentProperty(Property property, E owner, SimpleTypeHolder simpleTypeHolder); |
520 | 523 |
|
| 524 | + /** |
| 525 | + * Whether to create the {@link PersistentProperty}s for the given {@link TypeInformation}. |
| 526 | + * |
| 527 | + * @param typeInformation must not be {@literal null}. |
| 528 | + * @return {@literal true} properties should be created, {@literal false} otherwise |
| 529 | + */ |
| 530 | + protected boolean shouldCreateProperties(TypeInformation<?> typeInformation) { |
| 531 | + |
| 532 | + Class<?> type = typeInformation.getType(); |
| 533 | + |
| 534 | + return !typeInformation.isMap() && !isCollectionLike(type); |
| 535 | + } |
| 536 | + |
| 537 | + /** |
| 538 | + * In contrast to TypeInformation, we do not consider types implementing Streamable collection-like as domain types |
| 539 | + * can implement that type. |
| 540 | + * |
| 541 | + * @param type must not be {@literal null}. |
| 542 | + * @return |
| 543 | + * @see TypeInformation#isCollectionLike() |
| 544 | + */ |
| 545 | + private static boolean isCollectionLike(Class<?> type) { |
| 546 | + |
| 547 | + return type.isArray() // |
| 548 | + || Iterable.class.equals(type) // |
| 549 | + || Streamable.class.equals(type) // |
| 550 | + || Collection.class.isAssignableFrom(type) || CustomCollections.isCollection(type); |
| 551 | + } |
| 552 | + |
521 | 553 | @Override |
522 | 554 | public void afterPropertiesSet() { |
523 | 555 | initialize(); |
@@ -575,6 +607,7 @@ private PersistentPropertyCreator(E entity, Map<String, PropertyDescriptor> desc |
575 | 607 | this.remainingDescriptors = remainingDescriptors; |
576 | 608 | } |
577 | 609 |
|
| 610 | + @Override |
578 | 611 | public void doWith(Field field) { |
579 | 612 |
|
580 | 613 | String fieldName = field.getName(); |
|
0 commit comments