Query annotations for EntityViews in EntityViewRepository does not work
Hi, I was under the impression the @Query annotation would also work for EntityViews when using EntityViewRepository.
When trying the following example while debugging the SQL statements I can see the I expected is executed and only containing the fields defined in my EntityView but then in the same Thread also another SQL is following which seems like default Hibernate Query.
Followed by a ClassCastException from Node to NodeView.
From the exception it seems there are 2 proxies chained for the forRoot() but I dont know if thats normal.
@Transactional(readOnly = true)
public interface NodeViewRepository extends EntityViewRepository<NodeView, Long> {
@Query("SELECT n FROM Node n WHERE n.name = 'root'")
NodeView findRoot();
}
java.lang.ClassCastException: class test.domain.jpa.Node cannot be cast to class test.api.blaze.view.node.NodeView (test.domain.jpa.Node and test.api.blaze.view.node.NodeView are in unnamed module of loader org.springframework.boot.loader.launch.LaunchedClassLoader @f6f4d33)
at jdk.proxy2/jdk.proxy2.$Proxy310.findRoot(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220)
at jdk.proxy2/jdk.proxy2.$Proxy311.findRoot(Unknown Source)
at test.api.blaze.service.NodeViewService.findRoot(NodeViewService.java:54)
at test.api.blaze.controller.NodeViewController.findRoot(NodeViewController.java:64)
Also I am using @EnableJpaRepositories and @EnableBlazeRepositories together but scanning different packages if that matters.
Environment
version 1.6.11 integration-spring-data-3.1 Hibernate 6.4
Hey, it is not possible to use the @Query annotation along with entity views. You will have to write that query with JPA Criteria e.g.
@Transactional(readOnly = true)
public interface NodeViewRepository extends EntityViewRepository<NodeView, Long> {
default NodeView findRoot() {
return findOne( ( root, query, cb ) -> cb.equal( root.get("name"), cb.literal("root") ) );
}
NodeView findOne(Specification<Node> spec);
}
After digging a bit more through the issue it makes sense this wont work. Maybe the idea for our own Query annotation seems a bit overkill but should be doable I think? I'd like to hear your thoughts on what we would need and if that's even something interesting to have.
It would be interesting, but that depends on https://github.com/Blazebit/blaze-persistence/issues/252 which is not so easy to implement. If https://github.com/jakartaee/persistence/issues/29 were already available, I could just reuse the parser of the JPA provider instead, but having to implement a custom parser requires a lot of work and integration with the parsers of the JPA providers is probably even more work.