diff --git a/pom.xml b/pom.xml index fe01a16b6..3e7f1b4aa 100644 --- a/pom.xml +++ b/pom.xml @@ -221,6 +221,18 @@ 0.2.0 provided + + + + org.hibernate.orm + hibernate-jcache + + + + org.ehcache + ehcache + jakarta + diff --git a/src/main/java/org/tb/SalatApplication.java b/src/main/java/org/tb/SalatApplication.java index 05ef97d7a..1dd65290f 100644 --- a/src/main/java/org/tb/SalatApplication.java +++ b/src/main/java/org/tb/SalatApplication.java @@ -9,7 +9,6 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableJpaRepositories diff --git a/src/main/java/org/tb/common/configuration/HibernateSecondLevelCacheConfiguration.java b/src/main/java/org/tb/common/configuration/HibernateSecondLevelCacheConfiguration.java new file mode 100644 index 000000000..8dda4f258 --- /dev/null +++ b/src/main/java/org/tb/common/configuration/HibernateSecondLevelCacheConfiguration.java @@ -0,0 +1,37 @@ +package org.tb.common.configuration; + +import org.hibernate.cache.jcache.ConfigSettings; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; + +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.spi.CachingProvider; +import java.io.IOException; +import java.net.URI; + + +@Configuration +public class HibernateSecondLevelCacheConfiguration { + + @Bean + public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(ResourceLoader resourceLoader, + @Value("${salat.cache.max-entries}") String maxCacheEntries, + @Value("${salat.cache.expiry-tti}") String expiryTti) { + return (properties) -> { + try { + URI uri = resourceLoader.getResource("classpath:ehcache.xml").getURI(); + CachingProvider cachingProvider = Caching.getCachingProvider(); + System.setProperty("EHCACHE_EXPIRY_TTI", expiryTti); + System.setProperty("EHCACHE_RESOURCES_HEAP_ENTRIES", maxCacheEntries); + CacheManager cacheManager = cachingProvider.getCacheManager(uri, cachingProvider.getDefaultClassLoader()); + properties.put(ConfigSettings.CACHE_MANAGER, cacheManager); + } catch (IOException e) { + throw new RuntimeException(e); + } + }; + } +} diff --git a/src/main/java/org/tb/dailyreport/persistence/TimereportRepository.java b/src/main/java/org/tb/dailyreport/persistence/TimereportRepository.java index ba206ede0..6c56dadbd 100644 --- a/src/main/java/org/tb/dailyreport/persistence/TimereportRepository.java +++ b/src/main/java/org/tb/dailyreport/persistence/TimereportRepository.java @@ -6,8 +6,12 @@ import java.time.LocalDate; import java.util.List; import java.util.Optional; + +import jakarta.persistence.QueryHint; +import org.hibernate.jpa.HibernateHints; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import org.tb.dailyreport.domain.Timereport; @@ -15,16 +19,27 @@ @Repository public interface TimereportRepository extends CrudRepository, JpaSpecificationExecutor { + @QueryHints(value = { + @QueryHint(name = HibernateHints.HINT_CACHEABLE, value = "true"), + @QueryHint(name = HibernateHints.HINT_CACHE_REGION, value = "TimereportRepository.findAllByEmployeecontractIdAndReferencedayRefdate") + } + ) List findAllByEmployeecontractIdAndReferencedayRefdate(long employeecontractId, LocalDate refDate); List findAllByEmployeecontractIdAndReferencedayRefdateIsGreaterThanEqual(long employeecontractId, LocalDate refDate); List findAllByEmployeecontractIdAndStatusAndReferencedayRefdateIsLessThanEqual(long employeecontractId, String status, LocalDate date); + @QueryHints(value = { + @QueryHint(name = HibernateHints.HINT_CACHEABLE, value = "true"), + @QueryHint(name = HibernateHints.HINT_CACHE_REGION, value = "TimereportRepository.findAllByEmployeecontractIdAndReferencedayBetween") + } + ) @Query(""" select t from Timereport t - where t.employeecontract.id = :employeecontractId and - t.referenceday.refdate >= :begin and t.referenceday.refdate <= :end + where t.employeecontract.id = :employeecontractId + and t.referenceday.refdate >= :begin + and t.referenceday.refdate <= :end order by t.employeecontract.employee.sign asc, t.referenceday.refdate asc, t.employeeorder.suborder.customerorder.sign asc, diff --git a/src/main/java/org/tb/dailyreport/persistence/WorkingdayRepository.java b/src/main/java/org/tb/dailyreport/persistence/WorkingdayRepository.java index ad54bd2a3..a25c3d82d 100644 --- a/src/main/java/org/tb/dailyreport/persistence/WorkingdayRepository.java +++ b/src/main/java/org/tb/dailyreport/persistence/WorkingdayRepository.java @@ -4,7 +4,10 @@ import java.util.List; import java.util.Optional; +import jakarta.persistence.QueryHint; +import org.hibernate.jpa.HibernateHints; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import org.tb.dailyreport.domain.Workingday; @@ -12,6 +15,11 @@ @Repository public interface WorkingdayRepository extends CrudRepository { + @QueryHints(value = { + @QueryHint(name = HibernateHints.HINT_CACHEABLE, value = "true"), + @QueryHint(name = HibernateHints.HINT_CACHE_REGION, value = "WorkingdayRepository.findByRefdayAndEmployeecontractId") + } + ) Optional findByRefdayAndEmployeecontractId(LocalDate refday, long employeecontractId); List findAllByEmployeecontractId(long employeeContractId); diff --git a/src/main/java/org/tb/employee/persistence/EmployeecontractRepository.java b/src/main/java/org/tb/employee/persistence/EmployeecontractRepository.java index 69ab08282..2f92f8e09 100644 --- a/src/main/java/org/tb/employee/persistence/EmployeecontractRepository.java +++ b/src/main/java/org/tb/employee/persistence/EmployeecontractRepository.java @@ -3,8 +3,12 @@ import java.time.LocalDate; import java.util.List; import java.util.Optional; + +import jakarta.persistence.QueryHint; +import org.hibernate.jpa.HibernateHints; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; @@ -17,6 +21,11 @@ public interface EmployeecontractRepository extends PagingAndSortingRepository= :validAt or e.validUntil is null)") Optional findByEmployeeIdAndValidAt(long employeeId, LocalDate validAt); + @QueryHints(value = { + @QueryHint(name = HibernateHints.HINT_CACHEABLE, value = "true"), + @QueryHint(name = HibernateHints.HINT_CACHE_REGION, value = "EmployeecontractRepository.findAllValidAtAndNotHidden") + } + ) @Query(""" select e from Employeecontract e where (e.hide = false or e.hide is null) or (e.validFrom <= :date and (e.validUntil >= :date or e.validUntil is null)) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a495aaf52..5078fb975 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -33,13 +33,22 @@ spring: hibernate: format_sql: true show_sql: false - + use_sql_comments: true + generate_statistics: false + cache: + use_second_level_cache: true + use_query_cache: true + region: + factory_class: org.hibernate.cache.jcache.JCacheRegionFactory hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl ddl-auto: validate open-in-view: true + cache: + jcache: + config: classpath:ehcache.xml web: resources: chain: @@ -67,6 +76,9 @@ salat: mail-host: localhost auth-service: cache-expiry: 1s + cache: + max-entries: 1000 + expiry-tti: 10 springdoc: swagger-ui: path: /api/doc/ diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml new file mode 100644 index 000000000..945c914e9 --- /dev/null +++ b/src/main/resources/ehcache.xml @@ -0,0 +1,22 @@ + + + + + + + + + + ${EHCACHE_EXPIRY_TTI} + + + ${EHCACHE_RESOURCES_HEAP_ENTRIES} + + +