diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/EntityEventListener.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/EntityEventListener.java index d880deba5..0f6e277cc 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/EntityEventListener.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/EntityEventListener.java @@ -15,6 +15,7 @@ import org.hswebframework.ezorm.rdb.mapping.events.MappingEventTypes; import org.hswebframework.ezorm.rdb.mapping.events.ReactiveResultHolder; import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql; +import org.hswebframework.ezorm.rdb.operator.dml.update.UpdateOperator; import org.hswebframework.web.api.crud.entity.Entity; import org.hswebframework.web.bean.FastBeanCopier; import org.hswebframework.web.event.AsyncEvent; @@ -234,25 +235,46 @@ public class EntityEventListener implements EventListener, Ordered { .orElseThrow(UnsupportedOperationException::new); Object afterEntity = after.get(0); + Map copy = new HashMap<>(instance); - for (Map.Entry entry : instance.entrySet()) { - RDBColumnMetadata column = mapping.getColumnByName(entry.getKey()).orElse(null); - if (column == null) { + Map afterMap = FastBeanCopier.copy(afterEntity, new HashMap<>()); + + //设置实体类中指定的字段值 + for (Map.Entry entry : afterMap.entrySet()) { + RDBColumnMetadata column = mapping.getColumnByProperty(entry.getKey()).orElse(null); + if (column == null || !column.isUpdatable()) { continue; } - Object value = entry.getValue(); - if (value instanceof NullValue || - value instanceof NativeSql) { + + Object origin = copy.remove(column.getAlias()); + if (origin == null) { + origin = copy.remove(column.getName()); + } + + //按sql更新 忽略 + if (origin instanceof NativeSql) { continue; } - entry.setValue( - GlobalConfig - .getPropertyOperator() - .getProperty(afterEntity, column.getAlias()) - .orElse(entry.getValue()) - ); + //设置新的值 + instance.put(column.getAlias(), entry.getValue()); + } + + DSLUpdate operator = ctx + .get(ContextKeys.>source()) + .orElse(null); + if (operator != null) { + for (Map.Entry entry : copy.entrySet()) { + Object val = entry.getValue(); + if (val instanceof NullValue || val instanceof NativeSql) { + continue; + } + for (String col : copy.keySet()) { + operator.excludes(col); + } + } } + } protected void handleUpdateBefore(DSLUpdate update, EventContext context) { @@ -286,12 +308,17 @@ public class EntityEventListener implements EventListener, Ordered { updated.set(Tuples.of(list, after)); context.set(readyToUpdateBeforeContextKey, list); context.set(readyToUpdateAfterContextKey, after); + EntityPrepareModifyEvent event = new EntityPrepareModifyEvent(list, after, entityType); + return sendUpdateEvent(list, after, entityType, - EntityPrepareModifyEvent::new) - .then(Mono.fromRunnable(() -> prepareUpdateInstance(after, context))) - ; + (_list, _after, _type) -> event) + .then(Mono.fromRunnable(() -> { + if (event.hasListener()) { + prepareUpdateInstance(after, context); + } + })); }).then()) ); diff --git a/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/EntityEventListenerTest.java b/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/EntityEventListenerTest.java index 64b823bab..3fe9c75da 100644 --- a/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/EntityEventListenerTest.java +++ b/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/EntityEventListenerTest.java @@ -39,9 +39,10 @@ public class EntityEventListenerTest { private TestEntityListener listener; @Before - public void before(){ + public void before() { listener.reset(); } + @Test public void test() { Mono.just(EventTestEntity.of("test", 1)) @@ -55,8 +56,8 @@ public class EntityEventListenerTest { } @Test - public void testPrepareModify() { - EventTestEntity entity = EventTestEntity.of("prepare", null); + public void testPrepareModifySetNull() { + EventTestEntity entity = EventTestEntity.of("prepare-setNull", 20); reactiveRepository .insert(entity) .as(StepVerifier::create) @@ -66,8 +67,38 @@ public class EntityEventListenerTest { reactiveRepository .createUpdate() - .set("name","prepare-xx") - .where("id",entity.getId()) + .set("name", "prepare-setNull-set") + .setNull("age") + .where("id", entity.getId()) + .execute() + .as(StepVerifier::create) + .expectNextCount(1) + .verifyComplete(); + + reactiveRepository + .findById(entity.getId()) + .mapNotNull(EventTestEntity::getAge) + .as(StepVerifier::create) + .expectComplete() + .verify(); + + } + + @Test + public void testPrepareModify() { + EventTestEntity entity = EventTestEntity.of("prepare", 10); + reactiveRepository + .insert(entity) + .as(StepVerifier::create) + .expectNext(1) + .verifyComplete(); + Assert.assertEquals(listener.created.getAndSet(0), 1); + + reactiveRepository + .createUpdate() + .set("name", "prepare-xx") + .set("age", 20) + .where("id", entity.getId()) .execute() .as(StepVerifier::create) .expectNextCount(1) diff --git a/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/TestEntityListener.java b/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/TestEntityListener.java index 403968cac..33f097fa0 100644 --- a/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/TestEntityListener.java +++ b/hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/TestEntityListener.java @@ -99,6 +99,7 @@ public class TestEntityListener { for (EventTestEntity eventTestEntity : event.getAfter()) { if(eventTestEntity.getName().equals("prepare-xx")){ eventTestEntity.setName("prepare-0"); + eventTestEntity.setAge(null); } } })); diff --git a/hsweb-core/src/main/java/org/hswebframework/web/event/DefaultAsyncEvent.java b/hsweb-core/src/main/java/org/hswebframework/web/event/DefaultAsyncEvent.java index 9d7360d11..8307a4922 100644 --- a/hsweb-core/src/main/java/org/hswebframework/web/event/DefaultAsyncEvent.java +++ b/hsweb-core/src/main/java/org/hswebframework/web/event/DefaultAsyncEvent.java @@ -25,12 +25,14 @@ public class DefaultAsyncEvent implements AsyncEvent { } @Override - public void transformFirst(Function, Publisher> mapper) { + public synchronized void transformFirst(Function, Publisher> mapper) { + hasListener = true; this.first = Mono.fromDirect(mapper.apply(this.first)); } @Override - public void transform(Function, Publisher> mapper) { + public synchronized void transform(Function, Publisher> mapper) { + hasListener = true; this.async = Mono.fromDirect(mapper.apply(this.async)); }