Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
JingzhongChen opened this issue Nov 7, 2023 · 5 comments
Closed
Labels
type: bug A general bug

Comments

@JingzhongChen
Copy link

JingzhongChen commented Nov 7, 2023

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?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 7, 2023
@schauder
Copy link
Contributor

schauder commented Nov 7, 2023

Could you provide a full reproducer, preferable as a Github repository?

@schauder schauder added the status: waiting-for-feedback We need additional information before we can continue label Nov 7, 2023
@JingzhongChen
Copy link
Author

@schauder You can get the code from this site:
https://github.com/JingzhongChen/spring-data-jdbc-3.2.0-rc1-demo

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 7, 2023
@schauder
Copy link
Contributor

schauder commented Nov 7, 2023

Ouch, that looks like a bad one. Thanks for finding that.

Preliminary analysis suggests that somehow select statements generated for different repositories get mixed up with each other.

@schauder schauder added the type: bug A general bug label Nov 7, 2023
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 8, 2023
This makes a difference when a property is declared in a superclass of two entities.
In such a case the property is the same, but the owner is different.

Closes #2972
See spring-projects/spring-data-relational#1657
@schauder schauder removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Nov 8, 2023
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 8, 2023
This makes a difference when a property is declared in a superclass of two entities.
In such a case the property is the same, but the owner is different.

Closes #2972
See spring-projects/spring-data-relational#1657
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 8, 2023
This makes a difference when a property is declared in a superclass of two entities.
In such a case the property is the same, but the owner is different.

Closes #2972
Original pull request #2973
See spring-projects/spring-data-relational#1657
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 8, 2023
This makes a difference when a property is declared in a superclass of two entities.
In such a case the property is the same, but the owner is different.

Closes #2972
Original pull request #2973
See spring-projects/spring-data-relational#1657
@schauder
Copy link
Contributor

schauder commented Nov 8, 2023

This got fixed by spring-projects/spring-data-commons#2973

@schauder schauder closed this as completed Nov 8, 2023
@schauder schauder added this to the 3.1.6 (2023.0.6) milestone Nov 8, 2023
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 12, 2023
This reverts commit 633d125.

The change caused build failures for Spring Data JDBC.

See #2972
Original pull request #2973
See spring-projects/spring-data-relational#1657
schauder added a commit to spring-projects/spring-data-commons that referenced this issue Nov 12, 2023
This reverts commit 93913b0.

The change caused build failures for Spring Data JDBC.

See #2972
Original pull request #2973
See spring-projects/spring-data-relational#1657
@schauder schauder reopened this Nov 13, 2023
@schauder
Copy link
Contributor

Reopened since the change in commons caused other issue and had to be reverted.

schauder added a commit that referenced this issue Nov 13, 2023
Since a PersistencePropertyPath does NOT consider it's owner for equality, this is necessary.
to distinguish different AggregatePath instances based on a inherited property.

Closes #1657
mp911de added a commit that referenced this issue Nov 14, 2023
Revise aggregatePathCache generics. Reformat code.

See #1657
Original pull request: #1661
@mp911de mp911de changed the title Get error when using spring-data-jdbc-3.2.0-RC1 with model extended Base class : Required table ["USER"] by a SELECT column not imported by FROM ["POST"] or JOIN [] Using properties from a shared base class renders invalid queries Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
4 participants