Skip to content

Using properties from a shared base class renders invalid queries #1657

Closed
@JingzhongChen

Description

@JingzhongChen

My code:

package com.example.demo.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;

public abstract class BaseModel {
    @Id
    private Long id;

    @Version
    private Long version;

    public BaseModel() {
        super();
    }

    protected Long id() {
        return this.id;
    }

    protected void setId(Long id) {
        this.id = id;
    }

    protected Long getVersion() {
        return this.version;
    }

    protected void setVersion(Long version) {
        this.version = version;
    }
}
package com.example.demo.model;

public class User extends BaseModel {
    private Long userId;
    private String name;

    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package com.example.demo.model;

public class Post extends BaseModel {
    private Long postId;

    public Long getPostId() {
        return postId;
    }

    public void setPostId(Long postId) {
        this.postId = postId;
    }
}
package com.example.demo.repository;

import com.example.demo.model.User;
import org.springframework.data.repository.Repository;

public interface UserRepository extends Repository<User, Long> {
    User findByUserId(Long userId);
}
package com.example.demo.repository;

import com.example.demo.model.User;
import org.springframework.data.repository.Repository;

public interface UserRepository extends Repository<User, Long> {
    User findByUserId(Long userId);
}
package com.example.demo.repository;

import com.example.demo.model.Post;
import org.springframework.data.repository.Repository;

public interface PostRepository extends Repository<Post, Long> {
    Post findByPostId(Long postId);
}
package com.example.demo;

import com.example.demo.model.Post;
import com.example.demo.model.User;
import com.example.demo.repository.PostRepository;
import com.example.demo.repository.UserRepository;
import org.springframework.stereotype.Service;

@Service
public class ApplicationService {
    private final PostRepository postRepository;
    public final UserRepository userRepository;

    public ApplicationService(PostRepository postSDJRepository,
                              UserRepository userSDJRepository) {
        this.postRepository = postSDJRepository;
        this.userRepository = userSDJRepository;
    }

    public String test() {
        User user = this.userRepository.findByUserId(1L);
        Post post = this.postRepository.findByPostId(123L);
        return user.getName() + " " + post.getPostId();
    }
}

When run the test method of ApplicationService, I get the error below:

2023-11-07T17:30:17.740+08:00  INFO 4188 --- [nio-8001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-11-07T17:30:17.740+08:00  INFO 4188 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-11-07T17:30:17.741+08:00  INFO 4188 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-11-07T17:30:17.767+08:00 DEBUG 4188 --- [nio-8001-exec-1] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL query
2023-11-07T17:30:17.767+08:00 DEBUG 4188 --- [nio-8001-exec-1] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [SELECT `USER`.`ID` AS `ID`, `USER`.`NAME` AS `NAME`, `USER`.`USER_ID` AS `USER_ID`, `USER`.`VERSION` AS `VERSION` FROM `USER` WHERE `USER`.`USER_ID` = ?]
2023-11-07T17:30:17.767+08:00 DEBUG 4188 --- [nio-8001-exec-1] o.s.jdbc.datasource.DataSourceUtils      : Fetching JDBC Connection from DataSource
2023-11-07T17:30:17.786+08:00 ERROR 4188 --- [nio-8001-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalStateException: Required table ["USER"] by a SELECT column not imported by FROM ["POST"] or JOIN []] with root cause

java.lang.IllegalStateException: Required table ["USER"] by a SELECT column not imported by FROM ["POST"] or JOIN []
	at org.springframework.data.relational.core.sql.SelectValidator.doValidate(SelectValidator.java:63) ~[spring-data-relational-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.relational.core.sql.SelectValidator.validate(SelectValidator.java:49) ~[spring-data-relational-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.relational.core.sql.DefaultSelectBuilder.build(DefaultSelectBuilder.java:209) ~[spring-data-relational-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.relational.core.sql.SelectBuilder$BuildSelect.build(SelectBuilder.java:589) ~[spring-data-relational-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.complete(JdbcQueryCreator.java:180) ~[spring-data-jdbc-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.complete(JdbcQueryCreator.java:65) ~[spring-data-jdbc-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery.createQuery(PartTreeJdbcQuery.java:182) ~[spring-data-jdbc-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery.execute(PartTreeJdbcQuery.java:126) ~[spring-data-jdbc-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) ~[spring-data-commons-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) ~[spring-data-commons-3.2.0-RC1.jar:3.2.0-RC1]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:249) ~[spring-aop-6.1.0-RC2.jar:6.1.0-RC2]
	at jdk.proxy2/jdk.proxy2.$Proxy71.findByPostId(Unknown Source) ~[na:na]
	at com.example.demo.ApplicationService.test(ApplicationService.java:22) ~[classes/:na]
	at com.example.demo.Controller.test(Controller.java:21) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:253) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:181) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.15.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.15.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Alternatively, you can get the full reproducer from this site:
https://github.com/JingzhongChen/spring-data-jdbc-3.2.0-rc1-demo

It works in spring-data-jdbc:3.0.0, but it dose not work in spring-data-jdbc:3.2.0-RC1.
How can I fix this issue by any configuration?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions