Selaa lähdekoodia

fix optLocker for update(et,ew): ew is null & version not null

yuxiaobin 7 vuotta sitten
vanhempi
commit
799a3a65c2

+ 15 - 8
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/OptimisticLockerInterceptor.java

@@ -23,6 +23,7 @@ import org.apache.ibatis.plugin.Signature;
 import com.baomidou.mybatisplus.annotation.Version;
 import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
@@ -111,15 +112,18 @@ public class OptimisticLockerInterceptor implements Interceptor {
                 Object updatedVersionVal = getUpdatedVersionVal(originalVersionVal);
                 if (PARAM_UPDATE_METHOD_NAME.equals(updateMethodName)) {
                     // update(entity, wrapper)
-                    if (ew != null && ew instanceof AbstractWrapper) {
-                        AbstractWrapper aw = (AbstractWrapper) ew;
-                        if (null == originalVersionVal) {
-                            aw.isNull(entityVersionField.getColumnName());
-                        } else {
+                    if (originalVersionVal != null) {
+                        if (ew == null) {
+                            AbstractWrapper aw = new QueryWrapper();
                             aw.eq(entityVersionField.getColumnName(), originalVersionVal);
+                            map.put(NAME_ENTITY_WRAPPER, aw);
+                            versionField.set(et, updatedVersionVal);
+                        } else if (ew instanceof AbstractWrapper) {
+                            AbstractWrapper aw = (AbstractWrapper) ew;
+                            aw.eq(entityVersionField.getColumnName(), originalVersionVal);
+                            versionField.set(et, updatedVersionVal);
+                            //TODO: should remove version=oldval condition from aw; 0827
                         }
-                        versionField.set(et, updatedVersionVal);
-                        //TODO: should remove version=oldval condition from aw; 0827
                     }
                     return invocation.proceed();
                 } else {
@@ -127,7 +131,7 @@ public class OptimisticLockerInterceptor implements Interceptor {
                     Object resultObj = invocation.proceed();
                     if (resultObj instanceof Integer) {
                         Integer effRow = (Integer) resultObj;
-                        if (effRow != 0 && versionField != null && updatedVersionVal != null) {
+                        if (updatedVersionVal != null && effRow != 0 && versionField != null) {
                             //updated version value set to entity.
                             versionField.set(et, updatedVersionVal);
                         }
@@ -151,6 +155,9 @@ public class OptimisticLockerInterceptor implements Interceptor {
      */
     private void dealUpdateById(Class<?> entityClass, Object et, EntityField entityVersionField,
                                 Object originalVersionVal, Object updatedVersionVal, Map map) throws IllegalAccessException {
+        if (originalVersionVal == null) {
+            return;
+        }
         List<EntityField> fields = getEntityFields(entityClass);
         Map<String, Object> entityMap = new HashMap<>();
         for (EntityField ef : fields) {

+ 43 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2UserTest.java

@@ -2,6 +2,7 @@ package com.baomidou.mybatisplus.test.h2;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.List;
@@ -177,6 +178,48 @@ public class H2UserTest extends BaseTest {
         }
     }
 
+    @Test
+    public void testOptLocker4WrapperIsNull() {
+        H2User userInsert = new H2User();
+        userInsert.setName("optLockerTest");
+        userInsert.setAge(AgeEnum.THREE);
+        userInsert.setPrice(BigDecimal.TEN);
+        userInsert.setDesc("asdf");
+        userInsert.setTestType(1);
+        userInsert.setVersion(99);
+        userService.save(userInsert);
+
+        QueryWrapper<H2User> ew = new QueryWrapper<>();
+        ew.ge("age", AgeEnum.TWO.getValue());
+        Long id99 = null;
+        Map<Long, BigDecimal> idPriceMap = new HashMap<>();
+        for (H2User u : userService.list(ew)) {
+            System.out.println(u.getName() + "," + u.getAge() + "," + u.getVersion());
+            idPriceMap.put(u.getTestId(), u.getPrice());
+            if (u.getVersion() != null && u.getVersion() == 99) {
+                id99 = u.getTestId();
+            }
+        }
+        userService.update(new H2User().setPrice(BigDecimal.TEN).setVersion(99), null);
+        System.out.println("============after update");
+        ew = new QueryWrapper<>();
+        ew.ge("age", AgeEnum.TWO.getValue());
+        for (H2User u : userService.list(ew)) {
+            System.out.println(u.getName() + "," + u.getAge() + "," + u.getVersion());
+            if (id99 != null && u.getTestId().equals(id99)) {
+                Assert.assertEquals("optLocker should update version+=1", 100, u.getVersion().intValue());
+            } else {
+                Assert.assertEquals("other records should not be updated", idPriceMap.get(u.getTestId()), u.getPrice());
+            }
+        }
+        userService.update(new H2User().setPrice(BigDecimal.ZERO), null);
+        for (H2User u : userService.list(new QueryWrapper<>())) {
+            System.out.println(u.getName() + "," + u.getAge() + "," + u.getVersion());
+            Assert.assertEquals("all records should be updated", u.getPrice().setScale(2, RoundingMode.HALF_UP).intValue(), BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).intValue());
+        }
+
+    }
+
     @Test
     public void testEntityWrapperSelectSqlExcludeColumn() {
         QueryWrapper<H2User> ew = new QueryWrapper<>();