mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-05-07 21:55:57 +08:00
fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题 (#288)
* fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题 * fix: 修复无法设置null问题
This commit is contained in:
@@ -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<String, Object> copy = new HashMap<>(instance);
|
||||
|
||||
for (Map.Entry<String, Object> entry : instance.entrySet()) {
|
||||
RDBColumnMetadata column = mapping.getColumnByName(entry.getKey()).orElse(null);
|
||||
if (column == null) {
|
||||
Map<String, Object> afterMap = FastBeanCopier.copy(afterEntity, new HashMap<>());
|
||||
|
||||
//设置实体类中指定的字段值
|
||||
for (Map.Entry<String, Object> 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.<DSLUpdate<?, ?>>source())
|
||||
.orElse(null);
|
||||
if (operator != null) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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())
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -25,12 +25,14 @@ public class DefaultAsyncEvent implements AsyncEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transformFirst(Function<Mono<?>, Publisher<?>> mapper) {
|
||||
public synchronized void transformFirst(Function<Mono<?>, Publisher<?>> mapper) {
|
||||
hasListener = true;
|
||||
this.first = Mono.fromDirect(mapper.apply(this.first));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(Function<Mono<?>, Publisher<?>> mapper) {
|
||||
public synchronized void transform(Function<Mono<?>, Publisher<?>> mapper) {
|
||||
hasListener = true;
|
||||
this.async = Mono.fromDirect(mapper.apply(this.async));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user