Skip to content

Commit

Permalink
AbstractPersistentProperty now considers the owner for equals.
Browse files Browse the repository at this point in the history
This makes a difference when a property is declared in a superclass of two entities.
In such a case the property is the same, but the owner is different.

Closes #2972
See spring-projects/spring-data-relational#1657
  • Loading branch information
schauder committed Nov 8, 2023
1 parent 7a72a85 commit 213d89d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -41,6 +42,7 @@
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
* @author Jens Schauder
*/
public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>> implements PersistentProperty<P> {

Expand Down Expand Up @@ -87,7 +89,7 @@ public AbstractPersistentProperty(Property property, PersistentEntity<?, P> owne
this.association = Lazy.of(() -> isAssociation() ? createAssociation() : null);
this.owner = owner;

this.hashCode = Lazy.of(property::hashCode);
this.hashCode = Lazy.of(() -> Objects.hash(property, owner));
this.usePropertyAccess = Lazy.of(() -> owner.getType().isInterface() || CAUSE_FIELD.equals(getField()));

this.isAssociation = Lazy.of(() -> ASSOCIATION_TYPE != null && ASSOCIATION_TYPE.isAssignableFrom(rawType));
Expand Down Expand Up @@ -317,7 +319,7 @@ public boolean equals(@Nullable Object obj) {
return false;
}

return this.property.equals(that.property);
return this.property.equals(that.property) && this.owner.equals(that.owner);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,6 @@ void isEntityWorksForUntypedCollection() {
assertThat(getProperty(TestClassComplex.class, "collection").isEntity()).isFalse();
}

@Test // DATACMNS-121
void considersPropertiesEqualIfFieldEquals() {

var firstProperty = getProperty(FirstConcrete.class, "genericField");
var secondProperty = getProperty(SecondConcrete.class, "genericField");

assertThat(firstProperty).isEqualTo(secondProperty);
assertThat(firstProperty.hashCode()).isEqualTo(secondProperty.hashCode());
}

@Test // DATACMNS-180
void doesNotConsiderJavaTransientFieldsTransient() {
assertThat(getProperty(TestClassComplex.class, "transientField").isTransient()).isFalse();
Expand Down Expand Up @@ -207,7 +197,7 @@ void resolvesFieldNameWithUnderscoresCorrectly() {
@Test // DATACMNS-1139
void resolvesGenericsForRawType() {

var property = getProperty(FirstConcrete.class, "genericField");
var property = getProperty(Concrete.class, "genericField");

assertThat(property.getRawType()).isEqualTo(String.class);
}
Expand Down Expand Up @@ -240,6 +230,15 @@ void considersVavrMaps() {
assertThat(property.isMap()).isTrue();
}

@Test // GH-2972
void equalsConsidersOwner() {

SamplePersistentProperty id1 = getProperty(Inherited1.class, "id");
SamplePersistentProperty id2 = getProperty(Inherited2.class, "id");

assertThat(id1).isNotEqualTo(id2);
}

private <T> BasicPersistentEntity<T, SamplePersistentProperty> getEntity(Class<T> type) {
return new BasicPersistentEntity<>(TypeInformation.of(type));
}
Expand Down Expand Up @@ -277,11 +276,7 @@ class Generic<T> {

}

class FirstConcrete extends Generic<String> {

}

class SecondConcrete extends Generic<Integer> {
class Concrete extends Generic<String> {

}

Expand Down Expand Up @@ -412,4 +407,15 @@ interface JMoleculesAggregate extends AggregateRoot<JMoleculesAggregate, Identif
class VavrWrapper {
io.vavr.collection.Map<String, String> vavrMap;
}

class Base {
Long id;
}

class Inherited1 extends Base {
}

class Inherited2 extends Base {
}

}

0 comments on commit 213d89d

Please sign in to comment.