fix: 修复监听了EntityPrepareModifyEvent后,会变成更新全部字段问题.

This commit is contained in:
zhouhao
2024-07-02 11:59:07 +08:00
parent 3eb8343f3f
commit ddedde67d5
4 changed files with 41 additions and 8 deletions

View File

@@ -4,6 +4,7 @@ package org.hswebframework.web.crud.events;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.hswebframework.ezorm.core.GlobalConfig;
import org.hswebframework.ezorm.core.param.QueryParam;
import org.hswebframework.ezorm.rdb.events.EventListener;
@@ -222,11 +223,11 @@ public class EntityEventListener implements EventListener, Ordered {
// 回填修改后的字段到准备更新的数据中
// 用于实现通过事件来修改即将被修改的数据
protected void prepareUpdateInstance(List<Object> after, EventContext ctx) {
protected void prepareUpdateInstance(List<Object> before, List<Object> after, EventContext ctx) {
Map<String, Object> instance = ctx
.get(MappingContextKeys.updateColumnInstance)
.orElse(null);
if (after.size() != 1 || instance == null) {
if (before.size() != 1 || after.size() != 1 || instance == null) {
//不支持一次性更新多条数据时设置.
return;
}
@@ -235,9 +236,11 @@ public class EntityEventListener implements EventListener, Ordered {
.orElseThrow(UnsupportedOperationException::new);
Object afterEntity = after.get(0);
Object beforeEntity = before.get(0);
Map<String, Object> copy = new HashMap<>(instance);
Map<String, Object> afterMap = FastBeanCopier.copy(afterEntity, new HashMap<>());
Map<String, Object> beforeMap = FastBeanCopier.copy(beforeEntity, new HashMap<>());
//设置实体类中指定的字段值
for (Map.Entry<String, Object> entry : afterMap.entrySet()) {
@@ -246,10 +249,19 @@ public class EntityEventListener implements EventListener, Ordered {
continue;
}
//原始值
Object origin = copy.remove(column.getAlias());
if (origin == null) {
origin = copy.remove(column.getName());
}
//没有指定原始值,说明是通过事件指定的.
if (origin == null) {
//值相同忽略更新,可能是事件并没有修改这个字段.
if (Objects.equals(beforeMap.get(column.getAlias()), entry.getValue()) ||
Objects.equals(beforeMap.get(column.getName()), entry.getValue())) {
continue;
}
}
//按sql更新 忽略
if (origin instanceof NativeSql) {
@@ -262,15 +274,14 @@ public class EntityEventListener implements EventListener, Ordered {
DSLUpdate<?, ?> operator = ctx
.get(ContextKeys.<DSLUpdate<?, ?>>source())
.orElse(null);
if (operator != null) {
if (operator != null && MapUtils.isNotEmpty(copy)) {
for (Map.Entry<String, Object> entry : copy.entrySet()) {
Object val = entry.getValue();
if (val instanceof NullValue || val instanceof NativeSql) {
continue;
}
for (String col : copy.keySet()) {
operator.excludes(col);
}
operator.excludes(entry.getKey());
}
}
@@ -316,7 +327,7 @@ public class EntityEventListener implements EventListener, Ordered {
(_list, _after, _type) -> event)
.then(Mono.fromRunnable(() -> {
if (event.hasListener()) {
prepareUpdateInstance(after, context);
prepareUpdateInstance(list, after, context);
}
}));

View File

@@ -2,12 +2,14 @@ package org.hswebframework.web.crud;
import org.hswebframework.web.crud.entity.CustomTestEntity;
import org.hswebframework.web.crud.entity.TestEntity;
import org.hswebframework.web.crud.events.EntityBeforeModifyEvent;
import org.hswebframework.web.crud.service.TestEntityService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.event.EventListener;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -27,7 +29,7 @@ public class CrudTests {
entity.setExt("xxx");
entity.setAge(1);
entity.setName("test");
Mono.just(entity)
.cast(TestEntity.class)
.as(service::insert)
@@ -40,5 +42,13 @@ public class CrudTests {
.as(StepVerifier::create)
.expectNextMatches(e -> e instanceof CustomTestEntity)
.verifyComplete();
service.createUpdate()
.set("name", "test2")
.where("id", entity.getId())
.execute()
.as(StepVerifier::create)
.expectNext(1)
.verifyComplete();
}
}

View File

@@ -6,6 +6,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hswebframework.web.api.crud.entity.GenericEntity;
import org.hswebframework.web.bean.ToString;
import org.hswebframework.web.crud.annotation.EnableEntityEvent;
import org.hswebframework.web.crud.generator.Generators;
import javax.persistence.Column;
@@ -16,6 +17,7 @@ import javax.persistence.Table;
@Setter
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
@EnableEntityEvent
public class CustomTestEntity extends TestEntity {

View File

@@ -1,11 +1,14 @@
package org.hswebframework.web.crud.service;
import org.hswebframework.web.crud.entity.TestEntity;
import org.hswebframework.web.crud.events.EntityBeforeModifyEvent;
import org.hswebframework.web.crud.events.EntityCreatedEvent;
import org.hswebframework.web.crud.events.EntityPrepareModifyEvent;
import org.hswebframework.web.id.IDGenerator;
import org.junit.jupiter.api.Test;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Service
public class TestEntityService extends GenericReactiveCrudService<TestEntity,String> {
@@ -16,4 +19,11 @@ public class TestEntityService extends GenericReactiveCrudService<TestEntity,Str
System.out.println(event.getEntity());
}
@EventListener
public void listener(EntityPrepareModifyEvent<TestEntity> event){
System.out.println(event);
event.async(Mono.empty());
}
}