Closed spring-projects-issues closed 10 years ago
pascal gehl commented
Adding query hints for caching on CRUD methods (findAll, findOne...) seems to be a minimum feature, specially with ORM's second level caches. Do you have any timeline for this feature ?
Dmitry Angelov commented
IMHO at least its worth to move its priority one level up
Jan Goyvaerts commented
Is there a straightforward way to work around this issue ? I have massive amounts of find-by-id queries only producing cache misses. The second level cache is filled but is never used.
Because findOne is not cached ?
Martin Maier-Moessner commented
You could write your own base repository class and override findOne() or create a new method findOneCached(). In your custom implementation you then have direct access to the javax.persistence.Query instance, which has the setHint()-method you want to use.
For details see http://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/htmlsingle/#repositories.custom-behaviour-for-all-repositories
Jan Goyvaerts commented
I've added:
@Transactional(readOnly = true, propagation = Propagation.MANDATORY, rollbackFor = Throwable.class)
public T findById(@NotNull final Long id) {
return em.find(clazz, id, QUERY_HINTS);
}
Where clazz is the domain class of the constructor and QUERY_HINTS a static immutable map containing two Hibernate hints.
private static final Map<String, Object> QUERY_HINTS;
static {
final Map<String, Object> map = new HashMap<String, Object>();
// The official JPA2 hints don't seem to work for Hibernate 4.2.8.Final
// map.put("javax.persistence.cache.retrieveMode", CacheRetrieveMode.USE);
// map.put("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH);
map.put("org.hibernate.cacheable", true);
map.put("org.hibernate.cacheMode", CacheMode.NORMAL);
QUERY_HINTS = Collections.unmodifiableMap(map);
}
Making a query each each call is way too slow for me. Hence the usage of EntityManager.find()
Oliver Drotbohm commented
That's in place for the 1.6.0.BUILD-SNAPSHOTS. Feel free to give this a spin. I extended the previously existing infrastructure to detect @Lock
annotations to detect @QueryHints
as well.
I also added some caching of the metadata to make sure we don't waste too much time for reflection based annotation lookup for every method invocation.
We're shooting for an M1 by some time next week, so it'd be incredibly helpful to get some feedback about this
Jan Goyvaerts commented
I'll have a go today - I have other cats to skin, but I will be the last to discourage such speedy support ! :-)
Jan Goyvaerts commented
A bit of a hassle to upgrade from 1.4
=> new methods => relocated classes => wrong version of Data Common => errors against the usage of JsonProperty of Jackson.
But here we are !
I'm getting NPE at SimpleJpaRepository.applyRepositoryMethodMetadata(), line 528. Variable "crudMethodMetadata" is null.
Anything I can try ?
====================================================
java.lang.NullPointerException at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applyRepositoryMethodMetadata(SimpleJpaRepository.java:528) at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:475) at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:268) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:358) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:343) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy126.findAll(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198) at com.sun.proxy.$Proxy127.findAll(Unknown Source) at com.noesis.optimus.services.ProjectServiceImpl.findAll(ProjectServiceImpl.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) etc...
Oliver Drotbohm commented
Which versions are you using exactly?
Jan Goyvaerts commented
spring-data-commons-1.8.0.BUILD-20140311.113611-24.jar
and
spring-data-jpa-1.6.0.BUILD-20140312.143908-17.jar
Btw, there is no source jar for the Data Commons artifact
Oliver Drotbohm commented
Hm, there clearly is… see the repo.
How do you instantiate the repository? If you manually create them via JpaRepositoryFactory
you need to call setRepositoryMethodMetadata(…)
manually. Is it a CDI context maybe?
Jan Goyvaerts commented
Because I have specialized repositories I had to make a repository factory bean - as described in the documentation. I didn't know about the method meta data.
Do you have documentation about what kind of data it expects ?
Pascal Heus opened DATAJPA-173 and commented
Add support for
@QueryHints
annotations for CRUD methods such asfindAll(…)
,findOne(…)
, etc. For complex hierarchical structure, having the option to fine tune joins would be highly beneficial in terms of performanceReference URL: http://forum.springsource.org/showthread.php?113519-Query-Caching
Issue Links:
Referenced from: commits https://github.com/spring-projects/spring-data-jpa/commit/b71cd3e2f999d200ea02c17acfd24b1cded78ba2, https://github.com/spring-projects/spring-data-jpa/commit/5438c44c8f922cfb07f30ff7f5902631e1266224
9 votes, 10 watchers