Skip to content

Commit df0dce1

Browse files
authored
fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题 (#288)
* fix: 修复通过EntityPrepareModifyEvent重新设置可能无效问题 * fix: 修复无法设置null问题
1 parent 439f190 commit df0dce1

File tree

4 files changed

+82
-21
lines changed

4 files changed

+82
-21
lines changed

hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/EntityEventListener.java

+42-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.hswebframework.ezorm.rdb.mapping.events.ReactiveResultHolder;
1616
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
1717
import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql;
18+
import org.hswebframework.ezorm.rdb.operator.dml.update.UpdateOperator;
1819
import org.hswebframework.web.api.crud.entity.Entity;
1920
import org.hswebframework.web.bean.FastBeanCopier;
2021
import org.hswebframework.web.event.AsyncEvent;
@@ -234,25 +235,46 @@ protected void prepareUpdateInstance(List<Object> after, EventContext ctx) {
234235
.orElseThrow(UnsupportedOperationException::new);
235236

236237
Object afterEntity = after.get(0);
238+
Map<String, Object> copy = new HashMap<>(instance);
237239

238-
for (Map.Entry<String, Object> entry : instance.entrySet()) {
239-
RDBColumnMetadata column = mapping.getColumnByName(entry.getKey()).orElse(null);
240-
if (column == null) {
240+
Map<String, Object> afterMap = FastBeanCopier.copy(afterEntity, new HashMap<>());
241+
242+
//设置实体类中指定的字段值
243+
for (Map.Entry<String, Object> entry : afterMap.entrySet()) {
244+
RDBColumnMetadata column = mapping.getColumnByProperty(entry.getKey()).orElse(null);
245+
if (column == null || !column.isUpdatable()) {
241246
continue;
242247
}
243-
Object value = entry.getValue();
244-
if (value instanceof NullValue ||
245-
value instanceof NativeSql) {
248+
249+
Object origin = copy.remove(column.getAlias());
250+
if (origin == null) {
251+
origin = copy.remove(column.getName());
252+
}
253+
254+
//按sql更新 忽略
255+
if (origin instanceof NativeSql) {
246256
continue;
247257
}
248-
entry.setValue(
249-
GlobalConfig
250-
.getPropertyOperator()
251-
.getProperty(afterEntity, column.getAlias())
252-
.orElse(entry.getValue())
253-
);
258+
//设置新的值
259+
instance.put(column.getAlias(), entry.getValue());
260+
}
261+
262+
DSLUpdate<?, ?> operator = ctx
263+
.get(ContextKeys.<DSLUpdate<?, ?>>source())
264+
.orElse(null);
265+
if (operator != null) {
266+
for (Map.Entry<String, Object> entry : copy.entrySet()) {
267+
Object val = entry.getValue();
268+
if (val instanceof NullValue || val instanceof NativeSql) {
269+
continue;
270+
}
271+
for (String col : copy.keySet()) {
272+
operator.excludes(col);
273+
}
274+
}
254275

255276
}
277+
256278
}
257279

258280
protected void handleUpdateBefore(DSLUpdate<?, ?> update, EventContext context) {
@@ -286,12 +308,17 @@ protected void handleUpdateBefore(DSLUpdate<?, ?> update, EventContext context)
286308
updated.set(Tuples.of(list, after));
287309
context.set(readyToUpdateBeforeContextKey, list);
288310
context.set(readyToUpdateAfterContextKey, after);
311+
EntityPrepareModifyEvent event = new EntityPrepareModifyEvent(list, after, entityType);
312+
289313
return sendUpdateEvent(list,
290314
after,
291315
entityType,
292-
EntityPrepareModifyEvent::new)
293-
.then(Mono.fromRunnable(() -> prepareUpdateInstance(after, context)))
294-
;
316+
(_list, _after, _type) -> event)
317+
.then(Mono.fromRunnable(() -> {
318+
if (event.hasListener()) {
319+
prepareUpdateInstance(after, context);
320+
}
321+
}));
295322

296323
}).then())
297324
);

hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/EntityEventListenerTest.java

+35-4
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ public class EntityEventListenerTest {
3939
private TestEntityListener listener;
4040

4141
@Before
42-
public void before(){
42+
public void before() {
4343
listener.reset();
4444
}
45+
4546
@Test
4647
public void test() {
4748
Mono.just(EventTestEntity.of("test", 1))
@@ -54,9 +55,38 @@ public void test() {
5455

5556
}
5657

58+
@Test
59+
public void testPrepareModifySetNull() {
60+
EventTestEntity entity = EventTestEntity.of("prepare-setNull", 20);
61+
reactiveRepository
62+
.insert(entity)
63+
.as(StepVerifier::create)
64+
.expectNext(1)
65+
.verifyComplete();
66+
Assert.assertEquals(listener.created.getAndSet(0), 1);
67+
68+
reactiveRepository
69+
.createUpdate()
70+
.set("name", "prepare-setNull-set")
71+
.setNull("age")
72+
.where("id", entity.getId())
73+
.execute()
74+
.as(StepVerifier::create)
75+
.expectNextCount(1)
76+
.verifyComplete();
77+
78+
reactiveRepository
79+
.findById(entity.getId())
80+
.mapNotNull(EventTestEntity::getAge)
81+
.as(StepVerifier::create)
82+
.expectComplete()
83+
.verify();
84+
85+
}
86+
5787
@Test
5888
public void testPrepareModify() {
59-
EventTestEntity entity = EventTestEntity.of("prepare", null);
89+
EventTestEntity entity = EventTestEntity.of("prepare", 10);
6090
reactiveRepository
6191
.insert(entity)
6292
.as(StepVerifier::create)
@@ -66,8 +96,9 @@ public void testPrepareModify() {
6696

6797
reactiveRepository
6898
.createUpdate()
69-
.set("name","prepare-xx")
70-
.where("id",entity.getId())
99+
.set("name", "prepare-xx")
100+
.set("age", 20)
101+
.where("id", entity.getId())
71102
.execute()
72103
.as(StepVerifier::create)
73104
.expectNextCount(1)

hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/events/TestEntityListener.java

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public void handlePrepareModify(EntityPrepareModifyEvent<EventTestEntity> event)
9999
for (EventTestEntity eventTestEntity : event.getAfter()) {
100100
if(eventTestEntity.getName().equals("prepare-xx")){
101101
eventTestEntity.setName("prepare-0");
102+
eventTestEntity.setAge(null);
102103
}
103104
}
104105
}));

hsweb-core/src/main/java/org/hswebframework/web/event/DefaultAsyncEvent.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ public synchronized void first(Publisher<?> publisher) {
2525
}
2626

2727
@Override
28-
public void transformFirst(Function<Mono<?>, Publisher<?>> mapper) {
28+
public synchronized void transformFirst(Function<Mono<?>, Publisher<?>> mapper) {
29+
hasListener = true;
2930
this.first = Mono.fromDirect(mapper.apply(this.first));
3031
}
3132

3233
@Override
33-
public void transform(Function<Mono<?>, Publisher<?>> mapper) {
34+
public synchronized void transform(Function<Mono<?>, Publisher<?>> mapper) {
35+
hasListener = true;
3436
this.async = Mono.fromDirect(mapper.apply(this.async));
3537
}
3638

0 commit comments

Comments
 (0)