17
17
18
18
import java .beans .PropertyDescriptor ;
19
19
import java .lang .reflect .Field ;
20
+ import java .lang .reflect .Method ;
20
21
import java .lang .reflect .Modifier ;
21
22
import java .util .Collection ;
22
23
import java .util .Collections ;
32
33
33
34
import org .slf4j .Logger ;
34
35
import org .slf4j .LoggerFactory ;
36
+
35
37
import org .springframework .beans .BeanUtils ;
36
38
import org .springframework .beans .BeansException ;
37
39
import org .springframework .beans .factory .InitializingBean ;
64
66
import org .springframework .data .util .TypeInformation ;
65
67
import org .springframework .lang .Nullable ;
66
68
import org .springframework .util .Assert ;
67
- import org .springframework .util .ClassUtils ;
68
69
import org .springframework .util .ReflectionUtils ;
69
70
import org .springframework .util .ReflectionUtils .FieldCallback ;
70
71
import org .springframework .util .ReflectionUtils .FieldFilter ;
@@ -555,10 +556,9 @@ private void createAndRegisterProperty(Property input) {
555
556
return ;
556
557
}
557
558
558
- if (isKotlinOverride (property , input )) {
559
+ if (shouldSkipOverrideProperty (property )) {
559
560
return ;
560
561
}
561
-
562
562
entity .addPersistentProperty (property );
563
563
564
564
if (property .isAssociation ()) {
@@ -572,39 +572,86 @@ private void createAndRegisterProperty(Property input) {
572
572
property .getPersistentEntityTypes ().forEach (AbstractMappingContext .this ::addPersistentEntity );
573
573
}
574
574
575
- private boolean isKotlinOverride (P property , Property input ) {
575
+ protected boolean shouldSkipOverrideProperty (P property ) {
576
576
577
- if (!KotlinDetector .isKotlinPresent () || !input .getField ().isPresent ()) {
578
- return false ;
579
- }
577
+ P existingProperty = entity .getPersistentProperty (property .getName ());
580
578
581
- Field field = input .getField ().get ();
582
- if (!KotlinDetector .isKotlinType (field .getDeclaringClass ())) {
579
+ if (existingProperty == null ) {
583
580
return false ;
584
581
}
585
582
586
- for (P existingProperty : entity ) {
583
+ Class <?> declaringClass = getDeclaringClass (property );
584
+ Class <?> existingDeclaringClass = getDeclaringClass (existingProperty );
587
585
588
- if (!property .getName ().equals (existingProperty .getName ())) {
589
- continue ;
590
- }
586
+ Class <?> propertyType = getPropertyType (property );
587
+ Class <?> existingPropertyType = getPropertyType (existingProperty );
591
588
592
- if (field .getDeclaringClass () != entity .getType ()
593
- && ClassUtils .isAssignable (field .getDeclaringClass (), entity .getType ())) {
589
+ if (!existingPropertyType .isAssignableFrom (propertyType )) {
594
590
595
- if (LOGGER .isTraceEnabled ()) {
596
- LOGGER .trace (String .format ("Skipping '%s.%s' property declaration shadowed by '%s %s' in '%s'. " ,
597
- field .getDeclaringClass ().getName (), property .getName (), property .getType ().getSimpleName (),
598
- property .getName (), entity .getType ().getSimpleName ()));
599
- }
600
- return true ;
591
+ if (LOGGER .isDebugEnabled ()) {
592
+ LOGGER .warn (String .format ("Offending property declaration in '%s %s.%s' shadowing '%s %s.%s' in '%s'. " ,
593
+ propertyType .getSimpleName (), declaringClass .getName (), property .getName (),
594
+ existingPropertyType .getSimpleName (), existingDeclaringClass .getName (), existingProperty .getName (),
595
+ entity .getType ().getSimpleName ()));
601
596
}
597
+
598
+ return true ;
602
599
}
603
600
604
601
return false ;
605
602
}
603
+
604
+ private Class <?> getDeclaringClass (PersistentProperty <?> persistentProperty ) {
605
+
606
+ Field field = persistentProperty .getField ();
607
+ if (field != null ) {
608
+ return field .getDeclaringClass ();
609
+ }
610
+
611
+ Method accessor = persistentProperty .getGetter ();
612
+
613
+ if (accessor == null ) {
614
+ accessor = persistentProperty .getSetter ();
615
+ }
616
+
617
+ if (accessor == null ) {
618
+ accessor = persistentProperty .getWither ();
619
+ }
620
+
621
+ if (accessor != null ) {
622
+ return accessor .getDeclaringClass ();
623
+ }
624
+
625
+ return persistentProperty .getOwner ().getType ();
626
+ }
627
+
628
+ private Class <?> getPropertyType (PersistentProperty <?> persistentProperty ) {
629
+
630
+ Field field = persistentProperty .getField ();
631
+ if (field != null ) {
632
+ return field .getType ();
633
+ }
634
+
635
+ Method getter = persistentProperty .getGetter ();
636
+ if (getter != null ) {
637
+ return getter .getReturnType ();
638
+ }
639
+
640
+ Method setter = persistentProperty .getSetter ();
641
+ if (setter != null ) {
642
+ return setter .getParameterTypes ()[0 ];
643
+ }
644
+
645
+ Method wither = persistentProperty .getWither ();
646
+ if (wither != null ) {
647
+ return wither .getParameterTypes ()[0 ];
648
+ }
649
+
650
+ return persistentProperty .getType ();
651
+ }
606
652
}
607
653
654
+
608
655
/**
609
656
* Filter rejecting static fields as well as artificially introduced ones. See
610
657
* {@link PersistentPropertyFilter#UNMAPPED_PROPERTIES} for details.
0 commit comments