From e7ffc7bdc148386da323e1e99d06823ffc476b29 Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Wed, 24 Jan 2018 03:39:10 +0100 Subject: [PATCH] reduce database hits --- .../multipart/Rfc1341MultipartResolver.java | 2 +- .../acra/sql/data/ReportRepository.java | 28 ++++--------------- .../java/com/faendir/acra/sql/model/App.java | 3 +- .../java/com/faendir/acra/sql/model/Bug.java | 3 +- .../com/faendir/acra/sql/model/Report.java | 3 +- .../faendir/acra/sql/util/CountResult.java | 4 +-- .../com/faendir/acra/ui/view/ReportView.java | 2 +- .../acra/ui/view/tabs/PropertiesTab.java | 23 ++++++++++++++- 8 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/faendir/acra/service/multipart/Rfc1341MultipartResolver.java b/src/main/java/com/faendir/acra/service/multipart/Rfc1341MultipartResolver.java index 9ee2771..394937f 100644 --- a/src/main/java/com/faendir/acra/service/multipart/Rfc1341MultipartResolver.java +++ b/src/main/java/com/faendir/acra/service/multipart/Rfc1341MultipartResolver.java @@ -13,7 +13,7 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver; public class Rfc1341MultipartResolver extends CommonsMultipartResolver { @NonNull @Override - protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { + protected FileUpload newFileUpload(@NonNull FileItemFactory fileItemFactory) { return new Rfc1341ServletFileUpload(fileItemFactory); } } diff --git a/src/main/java/com/faendir/acra/sql/data/ReportRepository.java b/src/main/java/com/faendir/acra/sql/data/ReportRepository.java index 1dbb572..7da6c75 100644 --- a/src/main/java/com/faendir/acra/sql/data/ReportRepository.java +++ b/src/main/java/com/faendir/acra/sql/data/ReportRepository.java @@ -4,19 +4,15 @@ import com.faendir.acra.sql.model.App; import com.faendir.acra.sql.model.Bug; import com.faendir.acra.sql.model.Report; import com.faendir.acra.sql.util.CountResult; -import com.faendir.acra.util.Utils; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.lang.NonNull; -import org.springframework.transaction.annotation.Transactional; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.stream.Stream; +import java.util.Optional; /** * @author Lukas @@ -27,7 +23,11 @@ public interface ReportRepository extends JpaRepository { Slice findAllByBugApp(@NonNull App app, @NonNull Pageable pageable); - Stream findAllByBugApp(@NonNull App app); + @Query("select report from Report report join fetch report.bug bug join fetch bug.app app where app = ?1") + List findAllByAppEager(@NonNull App app); + + @Query("select report from Report report join fetch report.bug bug join fetch bug.app app where report.id = ?1") + Optional findByIdEager(@NonNull String id); int countAllByBugApp(@NonNull App app); @@ -48,20 +48,4 @@ public interface ReportRepository extends JpaRepository { @SuppressWarnings("SpringDataRepositoryMethodReturnTypeInspection") @Query("select new com.faendir.acra.sql.util.CountResult(bug.id, count(report)) from Report report group by report.bug") List> countAllByBug(); - - @Transactional - default void reassignBugs(App app) { - Map bugs = new HashMap<>(); - try(Stream stream = findAllByBugApp(app)) { - stream.forEach(report -> { - String stacktrace = Utils.generifyStacktrace(report.getStacktrace(), app.getConfiguration()); - Bug bug = bugs.get(stacktrace); - if (bug == null) { - bug = new Bug(app, stacktrace, report.getVersionCode(), report.getDate()); - } - report.setBug(bug); - bugs.put(stacktrace, save(report).getBug()); - }); - } - } } diff --git a/src/main/java/com/faendir/acra/sql/model/App.java b/src/main/java/com/faendir/acra/sql/model/App.java index cd01d6f..a3518ae 100644 --- a/src/main/java/com/faendir/acra/sql/model/App.java +++ b/src/main/java/com/faendir/acra/sql/model/App.java @@ -8,6 +8,7 @@ import org.springframework.lang.NonNull; import javax.persistence.CascadeType; import javax.persistence.Embeddable; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -23,7 +24,7 @@ public class App { @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; - @OneToOne(cascade = CascadeType.ALL, optional = false, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, optional = false, orphanRemoval = true, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private User reporter; private Configuration configuration; diff --git a/src/main/java/com/faendir/acra/sql/model/Bug.java b/src/main/java/com/faendir/acra/sql/model/Bug.java index 45fe577..683f1f0 100644 --- a/src/main/java/com/faendir/acra/sql/model/Bug.java +++ b/src/main/java/com/faendir/acra/sql/model/Bug.java @@ -8,6 +8,7 @@ import org.springframework.lang.NonNull; import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -23,7 +24,7 @@ public class Bug { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; - @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false) + @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private App app; private boolean solved; diff --git a/src/main/java/com/faendir/acra/sql/model/Report.java b/src/main/java/com/faendir/acra/sql/model/Report.java index f280bc1..7e20b3b 100644 --- a/src/main/java/com/faendir/acra/sql/model/Report.java +++ b/src/main/java/com/faendir/acra/sql/model/Report.java @@ -11,6 +11,7 @@ import org.springframework.lang.NonNull; import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Transient; @@ -23,7 +24,7 @@ import java.util.Date; @Entity public class Report { @Id private String id; - @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false) + @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private Bug bug; @Type(type = "text") private String content; diff --git a/src/main/java/com/faendir/acra/sql/util/CountResult.java b/src/main/java/com/faendir/acra/sql/util/CountResult.java index e8a76a3..05fc762 100644 --- a/src/main/java/com/faendir/acra/sql/util/CountResult.java +++ b/src/main/java/com/faendir/acra/sql/util/CountResult.java @@ -5,8 +5,8 @@ package com.faendir.acra.sql.util; * @since 19.12.2017 */ public class CountResult { - T group; - long count; + private T group; + private long count; public CountResult(T group, long count) { this.group = group; diff --git a/src/main/java/com/faendir/acra/ui/view/ReportView.java b/src/main/java/com/faendir/acra/ui/view/ReportView.java index 8cc93d3..8c5c4e1 100644 --- a/src/main/java/com/faendir/acra/ui/view/ReportView.java +++ b/src/main/java/com/faendir/acra/ui/view/ReportView.java @@ -131,7 +131,7 @@ public class ReportView extends ParametrizedNamedView { @Override public Report validateAndParseFragment(@NonNull String fragment) { - return reportRepository.findById(fragment).orElse(null); + return reportRepository.findByIdEager(fragment).orElse(null); } private static class ExceptionAwareStreamSource implements StreamResource.StreamSource { diff --git a/src/main/java/com/faendir/acra/ui/view/tabs/PropertiesTab.java b/src/main/java/com/faendir/acra/ui/view/tabs/PropertiesTab.java index c903c2a..995d312 100644 --- a/src/main/java/com/faendir/acra/ui/view/tabs/PropertiesTab.java +++ b/src/main/java/com/faendir/acra/ui/view/tabs/PropertiesTab.java @@ -4,7 +4,9 @@ import com.faendir.acra.sql.data.AppRepository; import com.faendir.acra.sql.data.BugRepository; import com.faendir.acra.sql.data.ReportRepository; import com.faendir.acra.sql.model.App; +import com.faendir.acra.sql.model.Bug; import com.faendir.acra.sql.model.Permission; +import com.faendir.acra.sql.model.Report; import com.faendir.acra.sql.model.User; import com.faendir.acra.sql.user.UserManager; import com.faendir.acra.ui.NavigationManager; @@ -13,6 +15,7 @@ import com.faendir.acra.ui.view.base.ConfigurationLabel; import com.faendir.acra.ui.view.base.MyTabSheet; import com.faendir.acra.ui.view.base.Popup; import com.faendir.acra.ui.view.base.ValidatedField; +import com.faendir.acra.util.Utils; import com.vaadin.shared.ui.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -30,6 +33,9 @@ import org.vaadin.risto.stepper.IntStepper; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author Lukas @@ -95,7 +101,22 @@ public class PropertiesTab implements MyTabSheet.Tab { .addYesNoButtons(p -> { app.setConfiguration(new App.Configuration(matchByMessage.getValue(), ignoreInstanceIds.getValue(), ignoreAndroidLineNumbers.getValue())); appRepository.save(app); - reportRepository.reassignBugs(app); + Map bugs = new HashMap<>(); + List reports = reportRepository.findAllByAppEager(app); + reports.forEach(report -> { + String stacktrace = Utils.generifyStacktrace(report.getStacktrace(), app.getConfiguration()); + Bug bug = bugs.get(stacktrace); + if (bug == null) { + if (stacktrace.equals(report.getBug().getStacktrace())) { + bug = report.getBug(); + } else { + bug = new Bug(app, stacktrace, report.getVersionCode(), report.getDate()); + } + } + report.setBug(bug); + bugs.put(stacktrace, bug); + }); + reportRepository.saveAll(reports); bugRepository.deleteOrphans(); p.close(); })