Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Avoiding internal calls causes interceptor methods invalid. #1239

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

Open
abel533 wants to merge 1 commit into mybatis:master
base: master
Choose a base branch
Loading
from abel533:interceptor

Conversation

@abel533
Copy link
Contributor

@abel533 abel533 commented Apr 1, 2018
edited
Loading

There are a few internally invoked methods in the executor implementation that the interceptor cannot intercept.

Especially the following method:

<E> List<E> query(MappedStatement ms, Object parameterObject, 
 RowBounds rowBounds, ResultHandler resultHandler, 
 CacheKey key, BoundSql boundSql) throws SQLException

The parameters of this method are the most complete, and it is most appropriate to intercept this method.

Binding the intercepted object can be accomplished through the interface provided by Executor.

void setExecutorWrapper(Executor executor)

Call this method in the Configuration class.

executor = (Executor) interceptorChain.pluginAll(executor);
executor.setExecutorWrapper(executor);

Copy link
Member

harawata commented Apr 5, 2018

Thank you, @abel533 .

I'll try to look into it.
It might take some time, though (so many things to do 🤯).

By the way, you wrote 'cannot intercept', but what happens actually?
If there is any error message or stack trace, please add that information.

Cc-ing @emacarron

Copy link
Member

Um...I'm sorry. I am not familiar with plugins and couldn't understand the problem.
Could you create an executable example including configurations and failing assertions, please?

Copy link
Contributor Author

abel533 commented Apr 21, 2018

Don't be misled by specific plugins.

After all, how do I intercept the following method?

<E> List<E> query(MappedStatement ms, Object parameterObject, 
 RowBounds rowBounds, ResultHandler resultHandler, 
 CacheKey key, BoundSql boundSql) throws SQLException

Copy link
Contributor Author

abel533 commented Nov 22, 2018
edited
Loading

@harawata Please resolve this PR before the 3.5.0 release.

If you accept this PR, the interceptor will be more convenient to handle.

Copy link
Member

Hi @abel533 ,

If you want me to proceed, please provide a small project including a simple example plugin.
Here are some project templates if it helps.

Preferably, I would look for an alternative approach as the change in this PR looks strange. i.e. there seems to be no legitimate reason to call wrapper's methods instead of its own.
In any case, I need the example to understand the problem first.

Copy link
Contributor Author

abel533 commented Nov 23, 2018

@harawata I am not familiar with gradle, and I have the following error when creating a project:

Caused by: groovy.lang.MissingPropertyException: No such property: mybatis for class: SimpleTemplateScript4
 at SimpleTemplateScript4.run(SimpleTemplateScript4.groovy:1)
 at org.gradle.api.internal.file.copy.FilterChain3ドル.transform(FilterChain.java:121)
 at org.gradle.api.internal.file.copy.FilterChain3ドル.transform(FilterChain.java:110)
 at org.gradle.api.internal.ChainingTransformer.transform(ChainingTransformer.java:37)
 at org.gradle.api.internal.file.copy.FilterChain.transform(FilterChain.java:56)
 at org.gradle.api.internal.file.copy.FilterChain.transform(FilterChain.java:64)
 at org.gradle.api.internal.file.copy.DefaultFileCopyDetails.open(DefaultFileCopyDetails.java:93)
 at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:56)
 at org.gradle.api.internal.file.copy.DefaultFileCopyDetails.copyTo(DefaultFileCopyDetails.java:101)
 at org.gradle.api.internal.file.AbstractFileTreeElement.copyFile(AbstractFileTreeElement.java:93)
 at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:74)
 ... 156 more

I put the example directly here, and the comment says the reason.

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.Properties;
@Intercepts(
 @Signature(
 type = Executor.class,
 method = "query",
 //Cannot intercept the query method of 6 parameters now
 //This PR can solve this problem
 args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
 //The current version can only intercept the following method
 //args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
 )
)
public class QueryInterceptor implements Interceptor {
 @Override
 public Object intercept(Invocation invocation) throws Throwable {
 Object[] args = invocation.getArgs();
 //It is often necessary to use BoundSql in the interceptor, which is very inconvenient now.
 BoundSql boundSql = (BoundSql) args[5];
 System.out.println("SQL: " + boundSql.getSql());
 return invocation.proceed();
 }
 @Override
 public Object plugin(Object target) {
 return Plugin.wrap(target, this);
 }
 @Override
 public void setProperties(Properties properties) {
 }
}

I think it is very important to be able to intercept the following interface below.

public interface Executor {
 //others
 <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
 //others
 
}

Copy link
Member

@abel533 @harawata

I am not familiar with gradle, and I have the following error when creating a project:

Sorry, I've fixed build error. Please try again.
Thanks.

abel533 added a commit to abel533/mybatis-issues that referenced this pull request Nov 23, 2018
Copy link
Contributor Author

abel533 commented Nov 23, 2018
edited
Loading

@harawata I wrote an example. After merge this PR. This interceptor will work.
zip: gh-1239.zip
github: https://github.com/abel533/mybatis-issues/tree/master/gh-1239

Copy link
Member

Thank you, @abel533 !
I'll look into it.

Copy link
Member

I now understand what you want, but as you wrote, the six-arg-version of query method is an internally invoked method and is not intended to be intercepted, I think.

Copy link
Contributor Author

abel533 commented Nov 28, 2018

If it is for internal calls, why design it on the interface. I think this is a design mistake.

Rowbounds is a very useful parameter, and it is necessary to intercept 6 parameters.

Copy link
Member

I think this is a design mistake.

I don't know, maybe (as I wrote, I am not familiar with plugin design).
As overwriting private fields might not work in a future version of Java, I myself am not so keen on such enhancement anyway, but someone else might.

Copy link
Contributor Author

abel533 commented Nov 29, 2018

What should I do next?

Copy link
Member

@abel533 ,

For now, you should be able to use AspectJ to achieve what you want.
See the updated demo: https://github.com/harawata/mybatis-issues/tree/master/gh-1239
This commit contains the changes I made: harawata/mybatis-issues@fffa055

It uses AspectJ's LTW (load-time weaving) and you may have to specify javaagent VM option to start your app [1].

[1] I didn't dig deeper, but there seems to be some kind of workaround. See https://stackoverflow.com/q/22580352/1261766

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /