Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static dev.morphia.mapping.PropertyDiscovery.FIELDS;

Check warning on line 64 in core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java

View workflow job for this annotation

GitHub Actions / Critter (AOT)

dev.morphia.mapping.PropertyDiscovery in dev.morphia.mapping has been deprecated

Check warning on line 64 in core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java

View workflow job for this annotation

GitHub Actions / CodeAudits / Code Audits

dev.morphia.mapping.PropertyDiscovery in dev.morphia.mapping has been deprecated

Check warning on line 64 in core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java

View workflow job for this annotation

GitHub Actions / Build / Build / Build

dev.morphia.mapping.PropertyDiscovery in dev.morphia.mapping has been deprecated
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
Expand Down Expand Up @@ -528,33 +528,6 @@
}
}

@Override
public int hashCode() {
return Objects.hash(annotations, propertyModelsByName, propertyModelsByMappedName, creatorFactory,
discriminatorEnabled, discriminatorKey(), discriminator(), getType(), collectionName(), listeners);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof EntityModel)) {
return false;
}
final EntityModel that = (EntityModel) o;
return discriminatorEnabled == that.discriminatorEnabled
&& Objects.equals(annotations, that.annotations)
&& Objects.equals(propertyModelsByName, that.propertyModelsByName)
&& Objects.equals(propertyModelsByMappedName, that.propertyModelsByMappedName)
&& Objects.equals(creatorFactory, that.creatorFactory)
&& Objects.equals(discriminatorKey(), that.discriminatorKey())
&& Objects.equals(discriminator(), that.discriminator())
&& Objects.equals(getType(), that.getType())
&& Objects.equals(collectionName(), that.collectionName())
&& Objects.equals(listeners, that.listeners);
}

@Override
public String toString() {
String properties = propertyModelsByName.values().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;

Expand Down Expand Up @@ -174,12 +173,6 @@ Codec<?> getCodec() {
return codec;
}

@Override
public int hashCode() {
return Objects.hash(getName(), getTypeData(), getMappedName(), codec, getAccessor(), serialization,
annotationMap.values(), getNormalizedType());
}

/**
* @param document the Document get the value from
* @return the value from first mapping of this field
Expand Down Expand Up @@ -295,23 +288,6 @@ public boolean hasAnnotation(Class<? extends Annotation> type) {
return annotationMap.containsKey(type);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PropertyModel that)) {
return false;
}
return getName().equals(that.getName())
&& getTypeData().equals(that.getTypeData())
&& getMappedName().equals(that.getMappedName())
&& Objects.equals(codec, that.codec)
&& getAccessor().equals(that.getAccessor())
&& serialization.equals(that.serialization)
&& Objects.equals(getNormalizedType(), that.getNormalizedType());
}

/**
* @param datastore
* @return the custom codec to use if set or null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import dev.morphia.mapping.DiscriminatorFunction;
import dev.morphia.mapping.MapperType;
import dev.morphia.mapping.codec.pojo.EntityModel;
import dev.morphia.mapping.codec.pojo.PropertyModel;
import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel;
import dev.morphia.test.mapping.codec.harness.models.HarnessArrays;
import dev.morphia.test.mapping.codec.harness.models.HarnessCallbackCircle;
Expand Down Expand Up @@ -206,6 +207,25 @@ private static void assertCallbacks(String message, HarnessCallbackShape shape,
message + ": @PrePersist, @PostPersist, @PreLoad, @PostLoad counts");
}

@Test
void modelHashesAreStableAcrossEncoding() {
for (MapperType mapper : MapperType.values()) {
MorphiaDatastore datastore = datastore(Variant.DEFAULTS, mapper);
EntityModel model = datastore.getMapper().getEntityModel(HarnessScalars.class);
Set<EntityModel> models = new HashSet<>(Set.of(model));
Set<PropertyModel> properties = new HashSet<>(model.getProperties());

// encoding specializes each property's codec, which used to change its hash
Codec<HarnessScalars> codec = codec(datastore, HarnessScalars.class);
decode(codec, encode(codec, HarnessScalars.sample(), COLLECTIBLE));

assertTrue(models.contains(model), mapper + ": the model's hash changed");
for (PropertyModel property : model.getProperties()) {
assertTrue(properties.contains(property), mapper + ": the hash of " + property.getName() + " changed");
}
}
}

@Test
void readsLoadOnlyProperties() {
// @LoadOnly values are never written, so the fixtures can't show that they are read
Expand Down
2 changes: 1 addition & 1 deletion design/mapping-game-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ structural item covers are moved to that item (see Phases 4 and 5).
- Write the test first (`List<Shape>`, where `Shape` has `@PrePersist`).
- Fix it by delegating subtypes *before* running callbacks in `LifecycleEncoder`/`LifecycleDecoder`.

### 2.7 `PropertyModel.hashCode` includes the lazy codec (D5)
### ~~2.7 `PropertyModel.hashCode` includes the lazy codec (D5)~~
- Delete the `equals`/`hashCode` overrides on `EntityModel` and `PropertyModel`, so both compare by identity.
This also removes the deep `equals` cost on `CopyOnWriteArraySet.add` and in `EntityEncoder`.
- Audit tests for any that rely on structural equality.
Expand Down
Loading