fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题 (#288)

* fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题

* fix: 修复无法设置null问题
This commit is contained in:
老周
2024-05-15 11:34:25 +08:00
committed by GitHub
parent 439f19034f
commit df0dce11a2
4 changed files with 83 additions and 22 deletions

View File

@@ -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())
);

View File

@@ -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)

View File

@@ -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);
}
}
}));

View File

@@ -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));
}