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
This commit is contained in:
Gauthier Roebroeck 2019-12-18 11:44:36 +08:00
parent 02361e154f
commit 713c602e8d
9 changed files with 72 additions and 22 deletions

View file

@ -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

View file

@ -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")

View file

@ -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<Book, Long>, JpaSpecificationExecutor<Book> {
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
override fun findAll(pageable: Pageable): Page<Book>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findAllBySeriesId(seriesId: Long, pageable: Pageable): Page<Book>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findAllByMetadataStatusAndSeriesId(status: BookMetadata.Status, seriesId: Long, pageable: Pageable): Page<Book>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findBySeriesLibraryIn(seriesLibrary: Collection<Library>, pageable: Pageable): Page<Book>
fun findByUrl(url: URL): Book?
fun findAllByMetadataStatus(status: BookMetadata.Status): List<Book>
fun findAllByMetadataThumbnailIsNull(): List<Book>
fun findBySeriesLibraryIn(seriesLibrary: Collection<Library>, pageable: Pageable): Page<Book>
}

View file

@ -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<Library, Long> {
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
override fun findAll(sort: Sort): List<Library>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
override fun findAllById(ids: Iterable<Long>): List<Library>
fun existsByName(name: String): Boolean
}

View file

@ -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<Series, Long>, JpaSpecificationExecutor<Series> {
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
override fun findAll(pageable: Pageable): Page<Series>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findByLibraryIn(libraries: Collection<Library>): List<Series>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findByLibraryIn(libraries: Collection<Library>, sort: Sort): List<Series>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findByLibraryIn(libraries: Collection<Library>, page: Pageable): Page<Series>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findByLibraryId(libraryId: Long, sort: Sort): List<Series>
@QueryHints(QueryHint(name = CACHEABLE, value = "true"))
fun findByLibraryIdIn(libraryIDs: Collection<Long>): List<Series>
fun findByLibraryIdAndUrlNotIn(libraryId: Long, urls: Collection<URL>): List<Series>
fun findByLibraryIdAndUrl(libraryId: Long, url: URL): Series?
fun deleteByLibraryId(libraryId: Long)
fun findByLibraryIdIn(libraryIDs: Collection<Long>): List<Series>
}

View file

@ -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)))
}
}

View file

@ -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)))
}
}

View file

@ -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
}
}
}
}

View file

@ -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