From 1568ada5215b1b2e9ee7ffca28fcd6cbcef73944 Mon Sep 17 00:00:00 2001 From: MKaramavrov Date: Tue, 14 May 2024 16:31:14 +0300 Subject: [PATCH] dev.morphia.Datastore Thread Safety #2802 - fix for Mapper thread safety issue when mapped using the same discriminator value --- .../main/java/dev/morphia/mapping/Mapper.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/dev/morphia/mapping/Mapper.java b/core/src/main/java/dev/morphia/mapping/Mapper.java index 0d1a6e32cdb..0661611a9f9 100644 --- a/core/src/main/java/dev/morphia/mapping/Mapper.java +++ b/core/src/main/java/dev/morphia/mapping/Mapper.java @@ -77,6 +77,7 @@ public class Mapper { private final List> listeners = new ArrayList<>(); private final MorphiaConfig config; private final DiscriminatorLookup discriminatorLookup; + private final Object entityRegistrationMonitor = new Object(); /** * Creates a Mapper with the given options. @@ -567,22 +568,27 @@ private EntityModel register(EntityModel model, boolean validate) { var existing = mappedEntities.get(model.getType().getName()); if (existing != null) { return existing; + } else { + synchronized (entityRegistrationMonitor) { + existing = mappedEntities.get(model.getType().getName()); + if (existing != null) { + return existing; + } else { + mappedEntities.put(model.getType().getName(), model); + if (validate && !model.isInterface()) { + new MappingValidator().validate(this, model); + } + discriminatorLookup.addModel(model); + mappedEntitiesByCollection.computeIfAbsent(model.getCollectionName(), s -> new CopyOnWriteArraySet<>()).add(model); + + EntityModel superClass = model.getSuperClass(); + if (superClass != null) { + superClass.addSubtype(model); + } + return model; + } + } } - mappedEntities.put(model.getType().getName(), model); - - if (validate && !model.isInterface()) { - new MappingValidator() - .validate(this, model); - } - discriminatorLookup.addModel(model); - mappedEntitiesByCollection.computeIfAbsent(model.getCollectionName(), s -> new CopyOnWriteArraySet<>()) - .add(model); - EntityModel superClass = model.getSuperClass(); - if (superClass != null) { - superClass.addSubtype(model); - } - - return model; } private List getClasses(String packageName)