You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/06/14 06:59:30 UTC

[james-project] 08/28: [PERF] JPA: reuse EntityManager where possible (#1582)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch 3.8.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 859cd50d7f162450e7fdfc65a33f5b102742cd4e
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Fri Jun 9 13:58:48 2023 +0700

    [PERF] JPA: reuse EntityManager where possible (#1582)
---
 .../jpa/JPAMailboxSessionMapperFactory.java        |  8 +-
 .../james/mailbox/jpa/mail/JPAMessageMapper.java   | 15 ++--
 .../james/mailbox/jpa/mail/JPAModSeqProvider.java  | 16 ++--
 .../james/mailbox/jpa/mail/JPAUidProvider.java     | 13 +++-
 .../mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java   | 85 +++++++-------------
 .../jpa/quota/JPAPerUserMaxQuotaManager.java       | 90 +++++++++++++++++-----
 .../main/resources/META-INF/spring/mailbox-jpa.xml |  3 +-
 .../mailbox/jpa/quota/JPAPerUserMaxQuotaTest.java  |  2 +-
 .../mpt/imapmailbox/jpa/host/JPAHostSystem.java    |  2 +-
 9 files changed, 132 insertions(+), 102 deletions(-)

diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
index cb7e0103a9..b751e92d5b 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxSessionMapperFactory.java
@@ -28,6 +28,8 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.jpa.mail.JPAAnnotationMapper;
 import org.apache.james.mailbox.jpa.mail.JPAMailboxMapper;
 import org.apache.james.mailbox.jpa.mail.JPAMessageMapper;
+import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
+import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
 import org.apache.james.mailbox.jpa.user.JPASubscriptionMapper;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
@@ -45,11 +47,11 @@ import org.apache.james.mailbox.store.user.SubscriptionMapper;
 public class JPAMailboxSessionMapperFactory extends MailboxSessionMapperFactory {
 
     private final EntityManagerFactory entityManagerFactory;
-    private final UidProvider uidProvider;
-    private final ModSeqProvider modSeqProvider;
+    private final JPAUidProvider uidProvider;
+    private final JPAModSeqProvider modSeqProvider;
 
     @Inject
-    public JPAMailboxSessionMapperFactory(EntityManagerFactory entityManagerFactory, UidProvider uidProvider, ModSeqProvider modSeqProvider) {
+    public JPAMailboxSessionMapperFactory(EntityManagerFactory entityManagerFactory, JPAUidProvider uidProvider, JPAModSeqProvider modSeqProvider) {
         this.entityManagerFactory = entityManagerFactory;
         this.uidProvider = uidProvider;
         this.modSeqProvider = modSeqProvider;
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
index c9a05f7cc9..da2b5fd2a4 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
@@ -49,8 +49,6 @@ import org.apache.james.mailbox.model.MessageRange.Type;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.mail.MessageMapper;
-import org.apache.james.mailbox.store.mail.ModSeqProvider;
-import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.utils.ApplicableFlagCalculator;
 import org.apache.openjpa.persistence.ArgumentException;
@@ -70,10 +68,10 @@ public class JPAMessageMapper extends JPATransactionalMapper implements MessageM
     private static final int UNLIMITED = -1;
 
     private final MessageUtils messageMetadataMapper;
-    private final UidProvider uidProvider;
-    private final ModSeqProvider modSeqProvider;
+    private final JPAUidProvider uidProvider;
+    private final JPAModSeqProvider modSeqProvider;
 
-    public JPAMessageMapper(UidProvider uidProvider, ModSeqProvider modSeqProvider, EntityManagerFactory entityManagerFactory) {
+    public JPAMessageMapper(JPAUidProvider uidProvider, JPAModSeqProvider modSeqProvider, EntityManagerFactory entityManagerFactory) {
         super(entityManagerFactory);
         this.messageMetadataMapper = new MessageUtils(uidProvider, modSeqProvider);
         this.uidProvider = uidProvider;
@@ -326,12 +324,12 @@ public class JPAMessageMapper extends JPATransactionalMapper implements MessageM
 
     @Override
     public Optional<MessageUid> getLastUid(Mailbox mailbox) throws MailboxException {
-        return uidProvider.lastUid(mailbox);
+        return uidProvider.lastUid(mailbox, getEntityManager());
     }
 
     @Override
     public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
-        return modSeqProvider.highestModSeq(mailbox);
+        return modSeqProvider.highestModSeq(mailbox.getMailboxId(), getEntityManager());
     }
 
     @Override
@@ -356,9 +354,6 @@ public class JPAMessageMapper extends JPATransactionalMapper implements MessageM
         return save(mailbox, copy);
     }
 
-    /**
-     * @see org.apache.james.mailbox.store.mail.AbstractMessageMapper#save(Mailbox, MailboxMessage)
-     */
     protected MessageMetaData save(Mailbox mailbox, MailboxMessage message) throws MailboxException {
         try {
             // We need to reload a "JPA attached" mailbox, because the provide
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
index 6f4181916a..5f1414d32c 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
@@ -83,17 +83,23 @@ public class JPAModSeqProvider implements ModSeqProvider {
     }
 
     private ModSeq highestModSeq(JPAId mailboxId) throws MailboxException {
-        EntityManager manager = null;
+        EntityManager manager = factory.createEntityManager();
+        try {
+            return highestModSeq(mailboxId, manager);
+        } finally {
+            EntityManagerUtils.safelyClose(manager);
+        }
+    }
+
+    public ModSeq highestModSeq(MailboxId mailboxId, EntityManager manager) throws MailboxException {
+        JPAId jpaId = (JPAId) mailboxId;
         try {
-            manager = factory.createEntityManager();
             long highest = (Long) manager.createNamedQuery("findHighestModSeq")
-                .setParameter("idParam", mailboxId.getRawId())
+                .setParameter("idParam", jpaId.getRawId())
                 .getSingleResult();
             return ModSeq.of(highest);
         } catch (PersistenceException e) {
             throw new MailboxException("Unable to get highest mod-sequence for mailbox " + mailboxId.serialize(), e);
-        } finally {
-            EntityManagerUtils.safelyClose(manager);
         }
     }
 }
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAUidProvider.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAUidProvider.java
index 85e140eaa3..94e197b4f9 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAUidProvider.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAUidProvider.java
@@ -45,9 +45,16 @@ public class JPAUidProvider implements UidProvider {
 
     @Override
     public Optional<MessageUid> lastUid(Mailbox mailbox) throws MailboxException {
-        EntityManager manager = null;
+        EntityManager manager = factory.createEntityManager();
+        try {
+            return lastUid(mailbox, manager);
+        } finally {
+            EntityManagerUtils.safelyClose(manager);
+        }
+    }
+
+    public Optional<MessageUid> lastUid(Mailbox mailbox, EntityManager manager) throws MailboxException {
         try {
-            manager = factory.createEntityManager();
             JPAId mailboxId = (JPAId) mailbox.getMailboxId();
             long uid = (Long) manager.createNamedQuery("findLastUid").setParameter("idParam", mailboxId.getRawId()).getSingleResult();
             if (uid == 0) {
@@ -56,8 +63,6 @@ public class JPAUidProvider implements UidProvider {
             return Optional.of(MessageUid.of(uid));
         } catch (PersistenceException e) {
             throw new MailboxException("Unable to get last uid for mailbox " + mailbox, e);
-        } finally {
-            EntityManagerUtils.safelyClose(manager);
         }
     }
 
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
index fa1fcffaca..8b28dbba69 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
@@ -26,7 +26,6 @@ import javax.inject.Inject;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 
-import org.apache.james.backends.jpa.EntityManagerUtils;
 import org.apache.james.backends.jpa.TransactionRunner;
 import org.apache.james.core.Domain;
 import org.apache.james.core.quota.QuotaCountLimit;
@@ -43,12 +42,10 @@ import org.apache.james.mailbox.model.QuotaRoot;
 public class JPAPerUserMaxQuotaDAO {
 
     private static final long INFINITE = -1;
-    private final EntityManagerFactory entityManagerFactory;
     private final TransactionRunner transactionRunner;
 
     @Inject
     public JPAPerUserMaxQuotaDAO(EntityManagerFactory entityManagerFactory) {
-        this.entityManagerFactory = entityManagerFactory;
         this.transactionRunner = new TransactionRunner(entityManagerFactory);
     }
 
@@ -162,82 +159,52 @@ public class JPAPerUserMaxQuotaDAO {
         return storedValue;
     }
 
-    public Optional<QuotaSizeLimit> getGlobalMaxStorage() {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
-            MaxGlobalStorage storedValue = entityManager.find(MaxGlobalStorage.class, MaxGlobalStorage.DEFAULT_KEY);
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaSize(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
+    public Optional<QuotaSizeLimit> getGlobalMaxStorage(EntityManager entityManager) {
+        MaxGlobalStorage storedValue = entityManager.find(MaxGlobalStorage.class, MaxGlobalStorage.DEFAULT_KEY);
+        if (storedValue == null) {
+            return Optional.empty();
         }
+        return longToQuotaSize(storedValue.getValue());
     }
 
-    public Optional<QuotaCountLimit> getGlobalMaxMessage() {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
-            MaxGlobalMessageCount storedValue = entityManager.find(MaxGlobalMessageCount.class, MaxGlobalMessageCount.DEFAULT_KEY);
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaCount(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
+    public Optional<QuotaCountLimit> getGlobalMaxMessage(EntityManager entityManager) {
+        MaxGlobalMessageCount storedValue = entityManager.find(MaxGlobalMessageCount.class, MaxGlobalMessageCount.DEFAULT_KEY);
+        if (storedValue == null) {
+            return Optional.empty();
         }
+        return longToQuotaCount(storedValue.getValue());
     }
 
-    public Optional<QuotaSizeLimit> getMaxStorage(QuotaRoot quotaRoot) {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
-            MaxUserStorage storedValue = entityManager.find(MaxUserStorage.class, quotaRoot.getValue());
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaSize(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
+    public Optional<QuotaSizeLimit> getMaxStorage(EntityManager entityManager, QuotaRoot quotaRoot) {
+        MaxUserStorage storedValue = entityManager.find(MaxUserStorage.class, quotaRoot.getValue());
+        if (storedValue == null) {
+            return Optional.empty();
         }
+        return longToQuotaSize(storedValue.getValue());
     }
 
-    public Optional<QuotaCountLimit> getMaxMessage(QuotaRoot quotaRoot) {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
-            MaxUserMessageCount storedValue = entityManager.find(MaxUserMessageCount.class, quotaRoot.getValue());
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaCount(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
+    public Optional<QuotaCountLimit> getMaxMessage(EntityManager entityManager, QuotaRoot quotaRoot) {
+        MaxUserMessageCount storedValue = entityManager.find(MaxUserMessageCount.class, quotaRoot.getValue());
+        if (storedValue == null) {
+            return Optional.empty();
         }
+        return longToQuotaCount(storedValue.getValue());
     }
 
-    public Optional<QuotaCountLimit> getDomainMaxMessage(Domain domain) {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
+    public Optional<QuotaCountLimit> getDomainMaxMessage(EntityManager entityManager, Domain domain) {
             MaxDomainMessageCount storedValue = entityManager.find(MaxDomainMessageCount.class, domain.asString());
             if (storedValue == null) {
                 return Optional.empty();
             }
             return longToQuotaCount(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
     }
 
-    public Optional<QuotaSizeLimit> getDomainMaxStorage(Domain domain) {
-        EntityManager entityManager = entityManagerFactory.createEntityManager();
-        try {
-            MaxDomainStorage storedValue = entityManager.find(MaxDomainStorage.class, domain.asString());
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaSize(storedValue.getValue());
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
+    public Optional<QuotaSizeLimit> getDomainMaxStorage(EntityManager entityManager, Domain domain) {
+        MaxDomainStorage storedValue = entityManager.find(MaxDomainStorage.class, domain.asString());
+        if (storedValue == null) {
+            return Optional.empty();
         }
+        return longToQuotaSize(storedValue.getValue());
     }
 
 
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
index 8b29dbdb88..31658c0c6a 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
@@ -25,8 +25,11 @@ import java.util.function.Function;
 import java.util.stream.Stream;
 
 import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
 
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.backends.jpa.EntityManagerUtils;
 import org.apache.james.core.Domain;
 import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
@@ -39,13 +42,15 @@ import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableMap;
 
 import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
 
 public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
-
+    private final EntityManagerFactory entityManagerFactory;
     private final JPAPerUserMaxQuotaDAO dao;
 
     @Inject
-    public JPAPerUserMaxQuotaManager(JPAPerUserMaxQuotaDAO dao) {
+    public JPAPerUserMaxQuotaManager(EntityManagerFactory entityManagerFactory, JPAPerUserMaxQuotaDAO dao) {
+        this.entityManagerFactory = entityManagerFactory;
         this.dao = dao;
     }
 
@@ -111,7 +116,12 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
 
     @Override
     public Optional<QuotaCountLimit> getDomainMaxMessage(Domain domain) {
-        return dao.getDomainMaxMessage(domain);
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return dao.getDomainMaxMessage(entityManager, domain);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
     }
 
     @Override
@@ -122,7 +132,12 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
 
     @Override
     public Optional<QuotaSizeLimit> getDomainMaxStorage(Domain domain) {
-        return dao.getDomainMaxStorage(domain);
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return dao.getDomainMaxStorage(entityManager, domain);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
     }
 
     @Override
@@ -173,7 +188,12 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
 
     @Override
     public Optional<QuotaSizeLimit> getGlobalMaxStorage() {
-        return dao.getGlobalMaxStorage();
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return dao.getGlobalMaxStorage(entityManager);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
     }
 
     @Override
@@ -184,7 +204,12 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
 
     @Override
     public Optional<QuotaCountLimit> getGlobalMaxMessage() {
-        return dao.getGlobalMaxMessage();
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return dao.getGlobalMaxMessage(entityManager);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
     }
 
     @Override
@@ -193,26 +218,55 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
             .flatMap(Mono::justOrEmpty);
     }
 
+    @Override
+    public Publisher<QuotaDetails> quotaDetailsReactive(QuotaRoot quotaRoot) {
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        return Mono.zip(
+                Mono.fromCallable(() -> listMaxMessagesDetails(quotaRoot, entityManager)),
+                Mono.fromCallable(() -> listMaxStorageDetails(quotaRoot, entityManager)))
+            .map(tuple -> new QuotaDetails(tuple.getT1(), tuple.getT2()))
+            .subscribeOn(Schedulers.boundedElastic())
+            .doFinally(any -> EntityManagerUtils.safelyClose(entityManager));
+    }
+
     @Override
     public Map<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot quotaRoot) {
-        Function<Domain, Optional<QuotaCountLimit>> domainQuotaFunction = Throwing.function(this::getDomainMaxMessage).sneakyThrow();
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return listMaxMessagesDetails(quotaRoot, entityManager);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
+    }
+
+    private ImmutableMap<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot quotaRoot, EntityManager entityManager) {
+        Function<Domain, Optional<QuotaCountLimit>> domainQuotaFunction = Throwing.function(domain -> dao.getDomainMaxMessage(entityManager, domain));
         return Stream.of(
-            Pair.of(Quota.Scope.User, dao.getMaxMessage(quotaRoot)),
-            Pair.of(Quota.Scope.Domain, quotaRoot.getDomain().flatMap(domainQuotaFunction)),
-            Pair.of(Quota.Scope.Global, dao.getGlobalMaxMessage()))
-        .filter(pair -> pair.getValue().isPresent())
-        .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> value.getValue().get()));
+                Pair.of(Quota.Scope.User, dao.getMaxMessage(entityManager, quotaRoot)),
+                Pair.of(Quota.Scope.Domain, quotaRoot.getDomain().flatMap(domainQuotaFunction)),
+                Pair.of(Quota.Scope.Global, dao.getGlobalMaxMessage(entityManager)))
+            .filter(pair -> pair.getValue().isPresent())
+            .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> value.getValue().get()));
     }
 
     @Override
     public Map<Quota.Scope, QuotaSizeLimit> listMaxStorageDetails(QuotaRoot quotaRoot) {
-        Function<Domain, Optional<QuotaSizeLimit>> domainQuotaFunction = Throwing.function(this::getDomainMaxStorage).sneakyThrow();
+        EntityManager entityManager = entityManagerFactory.createEntityManager();
+        try {
+            return listMaxStorageDetails(quotaRoot, entityManager);
+        } finally {
+            EntityManagerUtils.safelyClose(entityManager);
+        }
+    }
+
+    private ImmutableMap<Quota.Scope, QuotaSizeLimit> listMaxStorageDetails(QuotaRoot quotaRoot, EntityManager entityManager) {
+        Function<Domain, Optional<QuotaSizeLimit>> domainQuotaFunction = Throwing.function(domain -> dao.getDomainMaxStorage(entityManager, domain));
         return Stream.of(
-            Pair.of(Quota.Scope.User, dao.getMaxStorage(quotaRoot)),
-            Pair.of(Quota.Scope.Domain, quotaRoot.getDomain().flatMap(domainQuotaFunction)),
-            Pair.of(Quota.Scope.Global, dao.getGlobalMaxStorage()))
-        .filter(pair -> pair.getValue().isPresent())
-        .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> value.getValue().get()));
+                Pair.of(Quota.Scope.User, dao.getMaxStorage(entityManager, quotaRoot)),
+                Pair.of(Quota.Scope.Domain, quotaRoot.getDomain().flatMap(domainQuotaFunction)),
+                Pair.of(Quota.Scope.Global, dao.getGlobalMaxStorage(entityManager)))
+            .filter(pair -> pair.getValue().isPresent())
+            .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> value.getValue().get()));
     }
 
     @Override
diff --git a/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml b/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml
index e0fa9d0fd8..c673f3bc97 100644
--- a/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml
+++ b/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml
@@ -98,7 +98,8 @@
     </bean>
 
     <bean id="jpaMaxQuotaManager" class="org.apache.james.mailbox.jpa.quota.JPAPerUserMaxQuotaManager">
-        <constructor-arg index="0" ref="jpa-per-user-max-quota-dao"/>
+        <constructor-arg index="0" ref="entityManagerFactory"/>
+        <constructor-arg index="1" ref="jpa-per-user-max-quota-dao"/>
     </bean>
     <bean id="jpaCurrentQuotaManager" class="org.apache.james.mailbox.jpa.quota.JpaCurrentQuotaManager">
         <constructor-arg index="0" ref="entityManagerFactory"/>
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaTest.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaTest.java
index 6c5df68fad..8cb8f8be85 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaTest.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaTest.java
@@ -31,7 +31,7 @@ class JPAPerUserMaxQuotaTest extends GenericMaxQuotaManagerTest {
 
     @Override
     protected MaxQuotaManager provideMaxQuotaManager() {
-        return new JPAPerUserMaxQuotaManager(new JPAPerUserMaxQuotaDAO(JPA_TEST_CLUSTER.getEntityManagerFactory()));
+        return new JPAPerUserMaxQuotaManager(JPA_TEST_CLUSTER.getEntityManagerFactory(), new JPAPerUserMaxQuotaDAO(JPA_TEST_CLUSTER.getEntityManagerFactory()));
     }
 
     @AfterEach
diff --git a/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java b/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
index f2ecfd6b74..b6da87ec69 100644
--- a/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
+++ b/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
@@ -111,7 +111,7 @@ public class JPAHostSystem extends JamesImapHostSystem {
         SessionProviderImpl sessionProvider = new SessionProviderImpl(authenticator, authorizator);
         DefaultUserQuotaRootResolver quotaRootResolver = new DefaultUserQuotaRootResolver(sessionProvider, mapperFactory);
         JpaCurrentQuotaManager currentQuotaManager = new JpaCurrentQuotaManager(entityManagerFactory);
-        maxQuotaManager = new JPAPerUserMaxQuotaManager(new JPAPerUserMaxQuotaDAO(entityManagerFactory));
+        maxQuotaManager = new JPAPerUserMaxQuotaManager(entityManagerFactory, new JPAPerUserMaxQuotaDAO(entityManagerFactory));
         StoreQuotaManager storeQuotaManager = new StoreQuotaManager(currentQuotaManager, maxQuotaManager);
         ListeningCurrentQuotaUpdater quotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, storeQuotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(maxQuotaManager, storeQuotaManager, quotaRootResolver);


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org