Avoid records as cache keys for performance reasons.
Fixes GH-2997.
This commit is contained in:
@@ -487,5 +487,42 @@ public class PropertyPath implements Streamable<PropertyPath> {
|
||||
return String.format("%s.%s", owningType.getType().getSimpleName(), toDotPath());
|
||||
}
|
||||
|
||||
private record Key(TypeInformation<?> type, String path) {};
|
||||
private static final class Key {
|
||||
|
||||
private final TypeInformation<?> type;
|
||||
private final String path;
|
||||
|
||||
private Key(TypeInformation<?> type, String path) {
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Key that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(this.type, that.type) &&
|
||||
Objects.equals(this.path, that.path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "Key[" +
|
||||
"type=" + type + ", " +
|
||||
"path=" + path + ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Comparator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -331,7 +332,7 @@ class EntityCallbackDiscoverer {
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
private record EntityCallbackAdapter<T> (EntityCallback<T> delegate,
|
||||
private record EntityCallbackAdapter<T>(EntityCallback<T> delegate,
|
||||
ResolvableType type) implements EntityCallback<T> {
|
||||
|
||||
boolean supports(ResolvableType callbackType, ResolvableType entityType) {
|
||||
@@ -342,17 +343,52 @@ class EntityCallbackDiscoverer {
|
||||
/**
|
||||
* Cache key for {@link EntityCallback}, based on event type and source type.
|
||||
*/
|
||||
private record CallbackCacheKey(ResolvableType callbackType,
|
||||
@Nullable Class<?> entityType) implements Comparable<CallbackCacheKey> {
|
||||
private static final class CallbackCacheKey implements Comparable<CallbackCacheKey> {
|
||||
|
||||
private static final Comparator<CallbackCacheKey> COMPARATOR = Comparators.<CallbackCacheKey> nullsHigh() //
|
||||
.thenComparing(it -> it.callbackType.toString()) //
|
||||
.thenComparing(it -> it.entityType.getName());
|
||||
|
||||
private final ResolvableType callbackType;
|
||||
private final Class<?> entityType;
|
||||
|
||||
private CallbackCacheKey(ResolvableType callbackType, Class<?> entityType) {
|
||||
|
||||
this.callbackType = callbackType;
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CallbackCacheKey other) {
|
||||
public int compareTo(@Nullable CallbackCacheKey other) {
|
||||
return COMPARATOR.compare(this, other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof CallbackCacheKey that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(this.callbackType, that.callbackType)
|
||||
&& Objects.equals(this.entityType, that.entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(callbackType, entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "CallbackCacheKey[" +
|
||||
"callbackType=" + callbackType + ", " +
|
||||
"entityType=" + entityType + ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping.context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -279,12 +270,55 @@ class PersistentPropertyPathFactory<E extends PersistentEntity<?, P>, P extends
|
||||
return properties;
|
||||
}
|
||||
|
||||
record TypeAndPath(TypeInformation<?> type, String path) {
|
||||
static final class TypeAndPath {
|
||||
|
||||
private final TypeInformation<?> type;
|
||||
private final String path;
|
||||
|
||||
private TypeAndPath(TypeInformation<?> type, String path) {
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public static TypeAndPath of(TypeInformation<?> type, String path) {
|
||||
return new TypeAndPath(type, path);
|
||||
}
|
||||
|
||||
public TypeInformation<?> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String path() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TypeAndPath that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(this.type, that.type)
|
||||
&& Objects.equals(this.path, that.path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "TypeAndPath[" +
|
||||
"type=" + type + ", " +
|
||||
"path=" + path + ']';
|
||||
}
|
||||
}
|
||||
|
||||
static class DefaultPersistentPropertyPaths<T, P extends PersistentProperty<P>>
|
||||
|
||||
Reference in New Issue
Block a user