Browse Source

bugfix for OptimisticLockerInterceptor

yuxiaobin 8 years ago
parent
commit
4a38485bc8

+ 17 - 9
mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/OptimisticLockerInterceptor.java

@@ -12,7 +12,6 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.ibatis.binding.MapperMethod;
 import org.apache.ibatis.binding.MapperMethod.ParamMap;
 import org.apache.ibatis.builder.StaticSqlSource;
 import org.apache.ibatis.exceptions.ExceptionFactory;
@@ -67,7 +66,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 	/**
 	 * 根据对象类型缓存version基本信息
 	 */
-	private static final Map<Class<?>, VersionCache> versionCache = new ConcurrentHashMap<Class<?>, VersionCache>();
+	private static final Map<String, VersionCache> versionCache = new ConcurrentHashMap<>();
 
 	/**
 	 * 根据version字段类型缓存的处理器
@@ -93,13 +92,15 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 		if (parameterObject instanceof ParamMap) {
 			//FIXME 这里还没处理
 			ParamMap<?> tt = (ParamMap<?>) parameterObject;
-			realClass = tt.get("param1").getClass();
-		} else if (ProxyFactory.isProxyClass(parameterClass)) {
+			parameterClass = tt.get("param1").getClass();
+		}
+		if (ProxyFactory.isProxyClass(parameterClass)) {
 			realClass = parameterClass.getSuperclass();
 		} else {
 			realClass = parameterClass;
 		}
-		VersionCache versionPo = versionCache.get(realClass);
+		String cacheKey = realClass.getName();
+		VersionCache versionPo = versionCache.get(cacheKey);
 		if (versionPo != null) {
 			if (versionPo.isVersionControl) {
 				processChangeSql(ms, parameterObject, versionPo);
@@ -125,10 +126,10 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 			if (versionField != null) {
 				versionField.setAccessible(true);
 				VersionCache cachePo = new VersionCache(true, versionColumn, versionField);
-				versionCache.put(parameterClass, cachePo);
+				versionCache.put(cacheKey, cachePo);
 				processChangeSql(ms, parameterObject, cachePo);
 			} else {
-				versionCache.put(parameterClass, new VersionCache(false));
+				versionCache.put(cacheKey, new VersionCache(false));
 			}
 		}
 		return invocation.proceed();
@@ -137,7 +138,14 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 	private void processChangeSql(MappedStatement ms, Object parameterObject, VersionCache versionPo) throws Exception {
 		Field versionField = versionPo.versionField;
 		String versionColumn = versionPo.versionColumn;
-		final Object versionValue = versionField.get(parameterObject);
+		Object realObject = null;
+		if (parameterObject instanceof ParamMap) {
+			ParamMap<?> tt = (ParamMap<?>) parameterObject;
+			realObject = tt.get("param1");
+		}else{
+			realObject = parameterObject;
+		}
+		final Object versionValue = versionField.get(realObject);
 		if (versionValue != null) {// 先判断传参是否携带version,没带跳过插件,不可能去数据库查吧
 			Configuration configuration = ms.getConfiguration();
 			BoundSql boundSql = ms.getBoundSql(parameterObject);
@@ -182,7 +190,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 							versionNewValue = versionValue;// not support
 							break;
 					}
-					versionField.set(parameterObject, versionNewValue);
+					versionField.set(realObject, versionNewValue);
 				} else {
 					// TODO: 自定义VersionHandler处理
 

+ 30 - 8
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLockerInterceptorJUnitTest.java

@@ -26,29 +26,51 @@ public class OptimisticLockerInterceptorJUnitTest extends UserTestBase{
 	
 	@Test
 	public void testUpdateWithoutVersionControl(){
-		User user = userService.selectById(11);
+		User user = userService.selectById(11);//if cacheEnabled=true, this object will be cached
 		Assert.assertEquals(1, user.getAge().intValue());
-		user.setVersion(null);
-		user.setAge(2);
-		userService.updateById(user);
+		User updateUser = new User();
+		updateUser.setId(user.getId());
+		updateUser.setAge(2);
+		userService.updateById(updateUser);
+		
 		user = userService.selectById(11);
 		Assert.assertEquals(2, user.getAge().intValue());
 		Assert.assertEquals(1, user.getVersion().intValue());
+		
+		User user2 = userService.selectById(12);
+		updateUser = new User();
+		updateUser.setAge(99);
+		updateUser.setPrice(new BigDecimal("9.99"));
+		userService.updateById(updateUser);
+		user2 = userService.selectById(12);
+		Assert.assertEquals(1, user2.getVersion().intValue());//test if version is cached in plugin [OK]
 	}
 	
 	@Test
 	public void testUpdateWithVersionControl(){
 		long userId = 12;
 		User user = userService.selectById(userId);
-		Assert.assertEquals(2, user.getAge().intValue());
-		user.setAge(3);
-		userService.updateById(user);
+		Assert.assertEquals(1, user.getVersion().intValue());
+		User updateUser = new User();
+		updateUser.setId(userId);
+		updateUser.setAge(3);
+		updateUser.setVersion(user.getVersion());
+		userService.updateById(updateUser);
+		user = userService.selectById(userId);
+		
+		Assert.assertEquals(3, user.getAge().intValue());
+		Assert.assertEquals(2, user.getVersion().intValue());
+		
 		User where = new User();
 		where.setId(userId);
+//		updateUser = new User();
+//		updateUser.setId(userId);
+//		updateUser.setAge(3);
+//		updateUser.setVersion(user.getVersion());
 		userService.update(user, new EntityWrapper<User>(where));
 		user = userService.selectById(userId);
 		Assert.assertEquals(3, user.getAge().intValue());
-		Assert.assertEquals(2, user.getVersion().intValue());
+		Assert.assertEquals(3, user.getVersion().intValue());
 	}
 	
 }