AArhin / simple-spring-memcached

Automatically exported from code.google.com/p/simple-spring-memcached
MIT License
0 stars 0 forks source link

The SSM and MyBatis3 integration failure. #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
MyBatis3 no longer need to write the interface implementation class, like below 
so: 

public interface UserDao {

    @ReadThroughSingleCache(namespace = "user", expiration = 3600)
    @Select(value = "SELECT * FROM user WHERE id = #{id}")
    User getUser(@ParameterValueKeyProvider Long id)

}

However, the SSM can not set the value of memcached server. How to do it?

Mac 10.8.1, Spring3.1.1, MyBatis3.1.1, SSM3.0.2

Original issue reported on code.google.com by zhaob...@gmail.com on 12 Sep 2012 at 9:07

GoogleCodeExporter commented 9 years ago
Please attach the simplest java project which I can use to reproduce this issue.

Original comment by ragno...@gmail.com on 12 Sep 2012 at 9:57

GoogleCodeExporter commented 9 years ago

Original comment by ragno...@gmail.com on 12 Sep 2012 at 10:41

GoogleCodeExporter commented 9 years ago
I've found some project on github 
(https://github.com/batizhao/spring-memcached-bootstrap) that uses SSM and 
MyBatis 3. Does it your project?

As you have noticed SSM works with MyBatis 2 but doesn't work with MyBatis 3. 
It's because SSM use AspectJ to intercept method invocations and it requires 
SSM annotations to be defined on the concrete class. Annotations in interfaces 
will not work (that way MyBatis 3 doesn't work).

I see two possible workarounds:
1. Wrap UserDao with another service UserDaoWrapper which is a concrete class 
with the same interface as UserDao and delegates all invocation to UserDao. Use 
SSM annotations on UserDaoWrapper. In other classes use only UserDaoWrapper.
2. You may also try Spring Cache (it works with annotations on interfaces) and 
use SSM as backend (storage). In such case instead of SSM annotations use 
Spring Cache annotations: @Cacheable, @CachePut, @CacheEvict.

I may add support of annotations on interfaces to SSM but not in near future.

Original comment by ragno...@gmail.com on 12 Sep 2012 at 8:45

GoogleCodeExporter commented 9 years ago
Thank you, spring-memcached-bootstrap that is my project, I'm trying to second 
solution (Spring Cache), if I have a problem I will back to you.

Original comment by zhaob...@gmail.com on 13 Sep 2012 at 1:40

GoogleCodeExporter commented 9 years ago
The second solution (Spring Cache) is ok. But the the Spring Cache annotation 
interface method above does not work.Why integration SSM work? This is 
code(https://github.com/batizhao/spring-mybatis-memcached).

Original comment by zhaob...@gmail.com on 13 Sep 2012 at 8:42

GoogleCodeExporter commented 9 years ago
Could you write more precisely what doesn't work and what behaviour you are 
expected?

Original comment by ragno...@gmail.com on 13 Sep 2012 at 8:54

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I found that the Spring Cache annotations it is not working on the interface 
method, only in the implementation class.but spring cache and SSM3 together, 
can set the value of memcached server.

Original comment by zhaob...@gmail.com on 13 Sep 2012 at 9:06

GoogleCodeExporter commented 9 years ago
How did you check that Spring Cache without SSM doesn't work?
What cache manager did you use?
Yesterday I tried Spring Cache with ConcurrentMapCacheManager on one of your 
projects (MyBatis3) and it worked.

Original comment by ragno...@gmail.com on 13 Sep 2012 at 9:17

GoogleCodeExporter commented 9 years ago
Please see springcache-mybatis3 
module(https://github.com/batizhao/spring-mybatis-memcached/tree/master/springca
che-mybatis3), perform UserDaoTest.testGetUser, to see the log, query the 
database every time.I hope that the second query from cache.

Original comment by zhaob...@gmail.com on 13 Sep 2012 at 10:03

GoogleCodeExporter commented 9 years ago
Could you explain me how you test cache's usage in UserDaoTest?
If you want to take advantage of cache you need to get/read/fetch the same 
value at least two times (first time the value is read from DB and inserted to 
cache, second time the value from cache is returned) or insert value to cache 
while inserting it to DB (by @UpdateSingleCache or @CachePut). In most of your 
tests you get each object only once.

Original comment by ragno...@gmail.com on 13 Sep 2012 at 5:37

GoogleCodeExporter commented 9 years ago
Step1: If Memcached, I tested continuously ran twice, then observed twice log 
will be displayed for the first time a database query, as below this:
----
INFO 2012-09-14 09:04:49,116 com.google.code.ssm.spring.SSMCache: Get 1000 from 
user
DEBUG 2012-09-14 09:04:49,202 org.apache.ibatis.logging.slf4j.Slf4jImpl: ooo 
Using Connection [org.hsqldb.jdbc.jdbcConnection@411b1d80]
DEBUG 2012-09-14 09:04:49,235 org.apache.ibatis.logging.slf4j.Slf4jImpl: ==>  
Preparing: SELECT * FROM user WHERE id = ? 
DEBUG 2012-09-14 09:04:49,280 org.apache.ibatis.logging.slf4j.Slf4jImpl: ==> 
Parameters: 1000(Long)
 INFO 2012-09-14 09:04:49,331 com.google.code.ssm.spring.SSMCache: Put 'me.batizhao.model.User@3d3c4c09[
  id=1000
  name=Tom
]' under key 1000 to user
----
Step2: This moment memcached log like below this:
----
<21 new auto-negotiating client connection
21: Client using the ascii protocol
<21 get 1000
>21 END
<21 set 1000 8 300 57
>21 STORED
<21 connection closed.
----
Step3: The second does not query the database only shows like below this:
----
 INFO 2012-09-14 09:05:35,748 com.google.code.ssm.spring.SSMCache: Get 1000 from user
 INFO 2012-09-14 09:05:35,879 me.batizhao.UserDaoTest: User: me.batizhao.model.User@677210a5[
  id=1000
  name=Tom
]
----
Step4: This moment memcached log like below this:
----
<21 new auto-negotiating client connection
21: Client using the ascii protocol
<21 get 1000
>21 sending key 1000
>21 END
<21 connection closed.

Original comment by zhaob...@gmail.com on 14 Sep 2012 at 1:16

GoogleCodeExporter commented 9 years ago
Sorry! On the Spring Cache, Yesterday, I may not know where the mistake. Today 
I got it.
If Spring Cache, I insert the following code in log4j:
----
<logger name="org.springframework.cache">
    <level value="DEBUG"/>
</logger>
----
Then I observed the log, I found @Cacheable can work:
----
DEBUG 2012-09-14 09:24:57,965 
org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource: 
Adding cacheable method 'getUser' with attribute: [CacheableOperation[public 
abstract me.batizhao.model.User 
me.batizhao.dao.UserDao.getUser(java.lang.Long)] caches=[user] | condition='' | 
key='']

Original comment by zhaob...@gmail.com on 14 Sep 2012 at 1:41

GoogleCodeExporter commented 9 years ago
So does everything work as it should?

Original comment by ragno...@gmail.com on 14 Sep 2012 at 4:51

GoogleCodeExporter commented 9 years ago
Yes.

Original comment by zhaob...@gmail.com on 14 Sep 2012 at 5:38

GoogleCodeExporter commented 9 years ago

Original comment by ragno...@gmail.com on 14 Sep 2012 at 5:45

GoogleCodeExporter commented 9 years ago
噢,no,我遇到了上面一样的问题

Original comment by bobo2...@gmail.com on 13 May 2014 at 10:03