From 713c602e8dcbd69ddfb22c27b8fb6299c78222a1 Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Wed, 18 Dec 2019 11:44:36 +0800 Subject: [PATCH] remove OneToOne association from BookMetadata to Book, as it cannot be lazy fetched and is not used fix configuration to enable Hibernate query cache enable query cache on all web controller facing queries, except on search --- .../org/gotson/komga/domain/model/Book.kt | 6 +---- .../gotson/komga/domain/model/BookMetadata.kt | 4 ---- .../domain/persistence/BookRepository.kt | 13 ++++++++++- .../domain/persistence/LibraryRepository.kt | 10 +++++++++ .../domain/persistence/SeriesRepository.kt | 19 +++++++++++++++- .../interfaces/web/rest/BookController.kt | 3 +-- .../interfaces/web/rest/SeriesController.kt | 3 +-- komga/src/main/resources/application.conf | 22 +++++++++++++++++++ komga/src/main/resources/application.yml | 14 ++++++------ 9 files changed, 72 insertions(+), 22 deletions(-) diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/Book.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/Book.kt index 3d968cb80..455de6775 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/model/Book.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/Book.kt @@ -52,11 +52,7 @@ class Book( @OneToOne(optional = false, orphanRemoval = true, cascade = [CascadeType.ALL], fetch = FetchType.LAZY) @JoinColumn(name = "book_metadata_id", nullable = false) - var metadata: BookMetadata = BookMetadata().also { it.book = this } - set(value) { - value.book = this - field = value - } + var metadata: BookMetadata = BookMetadata() @Column(name = "number", nullable = false, columnDefinition = "REAL") var number: Float = 0F diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/BookMetadata.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/BookMetadata.kt index a712d3b76..c3069585b 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/model/BookMetadata.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/BookMetadata.kt @@ -16,7 +16,6 @@ import javax.persistence.GeneratedValue import javax.persistence.Id import javax.persistence.JoinColumn import javax.persistence.Lob -import javax.persistence.OneToOne import javax.persistence.OrderColumn import javax.persistence.Table @@ -45,9 +44,6 @@ class BookMetadata( @Column(name = "id", nullable = false, unique = true) val id: Long = 0 - @OneToOne(optional = false, fetch = FetchType.LAZY, mappedBy = "metadata") - lateinit var book: Book - @ElementCollection(fetch = FetchType.LAZY) @CollectionTable(name = "book_metadata_page", joinColumns = [JoinColumn(name = "book_metadata_id")]) @OrderColumn(name = "number") diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/BookRepository.kt b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/BookRepository.kt index bddbbf34c..d8daf6b67 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/BookRepository.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/BookRepository.kt @@ -3,20 +3,31 @@ package org.gotson.komga.domain.persistence import org.gotson.komga.domain.model.Book import org.gotson.komga.domain.model.BookMetadata import org.gotson.komga.domain.model.Library +import org.hibernate.annotations.QueryHints.CACHEABLE import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaSpecificationExecutor +import org.springframework.data.jpa.repository.QueryHints import org.springframework.stereotype.Repository import java.net.URL +import javax.persistence.QueryHint @Repository interface BookRepository : JpaRepository, JpaSpecificationExecutor { + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + override fun findAll(pageable: Pageable): Page + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findAllBySeriesId(seriesId: Long, pageable: Pageable): Page + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findAllByMetadataStatusAndSeriesId(status: BookMetadata.Status, seriesId: Long, pageable: Pageable): Page + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + fun findBySeriesLibraryIn(seriesLibrary: Collection, pageable: Pageable): Page + fun findByUrl(url: URL): Book? fun findAllByMetadataStatus(status: BookMetadata.Status): List fun findAllByMetadataThumbnailIsNull(): List - fun findBySeriesLibraryIn(seriesLibrary: Collection, pageable: Pageable): Page } diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/LibraryRepository.kt b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/LibraryRepository.kt index f439f9556..d0d4d8366 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/LibraryRepository.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/LibraryRepository.kt @@ -1,10 +1,20 @@ package org.gotson.komga.domain.persistence import org.gotson.komga.domain.model.Library +import org.hibernate.annotations.QueryHints.CACHEABLE +import org.springframework.data.domain.Sort import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.QueryHints import org.springframework.stereotype.Repository +import javax.persistence.QueryHint @Repository interface LibraryRepository : JpaRepository { + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + override fun findAll(sort: Sort): List + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + override fun findAllById(ids: Iterable): List + fun existsByName(name: String): Boolean } diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/SeriesRepository.kt b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/SeriesRepository.kt index f4b169ddb..18d483b12 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/SeriesRepository.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/SeriesRepository.kt @@ -2,22 +2,39 @@ package org.gotson.komga.domain.persistence import org.gotson.komga.domain.model.Library import org.gotson.komga.domain.model.Series +import org.hibernate.annotations.QueryHints.CACHEABLE import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaSpecificationExecutor +import org.springframework.data.jpa.repository.QueryHints import org.springframework.stereotype.Repository import java.net.URL +import javax.persistence.QueryHint @Repository interface SeriesRepository : JpaRepository, JpaSpecificationExecutor { + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + override fun findAll(pageable: Pageable): Page + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findByLibraryIn(libraries: Collection): List + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findByLibraryIn(libraries: Collection, sort: Sort): List + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findByLibraryIn(libraries: Collection, page: Pageable): Page + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) fun findByLibraryId(libraryId: Long, sort: Sort): List + + @QueryHints(QueryHint(name = CACHEABLE, value = "true")) + fun findByLibraryIdIn(libraryIDs: Collection): List + fun findByLibraryIdAndUrlNotIn(libraryId: Long, urls: Collection): List fun findByLibraryIdAndUrl(libraryId: Long, url: URL): Series? fun deleteByLibraryId(libraryId: Long) - fun findByLibraryIdIn(libraryIDs: Collection): List + } diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/BookController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/BookController.kt index 7ef63af4a..091f17523 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/BookController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/BookController.kt @@ -72,8 +72,7 @@ class BookController( !principal.user.sharedAllLibraries -> specs.add(Book::series.`in`(seriesRepository.findByLibraryIn(principal.user.sharedLibraries))) !libraryIds.isNullOrEmpty() -> { - val libraries = libraryRepository.findAllById(libraryIds) - specs.add(Book::series.`in`(seriesRepository.findByLibraryIn(libraries))) + specs.add(Book::series.`in`(seriesRepository.findByLibraryIdIn(libraryIds))) } } diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/SeriesController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/SeriesController.kt index 63db79587..e70fc9181 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/SeriesController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/web/rest/SeriesController.kt @@ -63,8 +63,7 @@ class SeriesController( !principal.user.sharedAllLibraries -> specs.add(Series::library.`in`(principal.user.sharedLibraries)) !libraryIds.isNullOrEmpty() -> { - val libraries = libraryRepository.findAllById(libraryIds) - specs.add(Series::library.`in`(libraries)) + specs.add(Series::library.`in`(libraryRepository.findAllById(libraryIds))) } } diff --git a/komga/src/main/resources/application.conf b/komga/src/main/resources/application.conf index 9568d847c..e012a0698 100644 --- a/komga/src/main/resources/application.conf +++ b/komga/src/main/resources/application.conf @@ -64,4 +64,26 @@ caffeine.jcache { } } } + + default-update-timestamps-region { + monitoring { + statistics = true + } + policy { + maximum { + size = 500 + } + } + } + + default-query-results-region { + monitoring { + statistics = true + } + policy { + maximum { + size = 500 + } + } + } } diff --git a/komga/src/main/resources/application.yml b/komga/src/main/resources/application.yml index f233e4b3d..acd50903e 100644 --- a/komga/src/main/resources/application.yml +++ b/komga/src/main/resources/application.yml @@ -12,16 +12,16 @@ spring: cache-public: true max-age: 365d jpa.properties: - javax.persistence.sharedCache.mode: ENABLE_SELECTIVE + javax: + persistence.sharedCache.mode: ENABLE_SELECTIVE + cache.provider: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider hibernate: generate_statistics: true session.events.log: false - hibernate: - cache: - use_second_level_cache: true - use_query_cache: true - region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory - javax.cache.provider: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider + cache: + use_second_level_cache: true + use_query_cache: true + region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory server.servlet.session.timeout: 7d