简体   繁体   中英

Spring Data MongoDB auditing doesn't work for embedded documents

I'm trying to introduce auditing by using Spring Data MongoDB @LastModifiedDate annotation. It works fine for top-level documents but I've faced with the problem for embedded objects.

For example:

@Document(collection = "parent")
class ParentDocument {

    @Id
    String id;        

    @LastModifiedDate
    DateTime updated;

    List<ChildDocument> children;  

}

@Document
class ChildDocument {

    @Id
    String id;        

    @LastModifiedDate
    DateTime updated;

}

By default, when I save parentDocument instance with inner children list, updated value is set only for parentDocument but not for any object from the children list. But in this case I want to audit them too. Is it possible to solve this problem somehow?

I've decided to solve it using custom ApplicationListener

public class CustomAuditingEventListener implements 
        ApplicationListener<BeforeConvertEvent<Object>> {

    @Override
    public void onApplicationEvent(BeforeConvertEvent<Object> event) {
        Object source = event.getSource();
        if (source instanceof ParentDocument) {
            DateTime currentTime = DateTime.now();
            ParentDocument parent = (ParentDocument) source;
            parent.getChildren().forEach(item -> item.setUpdated(currentTime));
        }
    }
}

And then add corresponding bean to the application context

<bean id="customAuditingEventListener" class="app.CustomAuditingEventListener"/>

I don't know what DateTime type is, but with LocalDateTime next configuration should work in spring-boot-starter-data-mongodb-reactive projects:

@Configuration
public class LastModifiedDateConfig implements ApplicationListener<BeforeConvertEvent<Object>> {

  @Override
  public void onApplicationEvent(BeforeConvertEvent<Object> event) {

    Optional.ofNullable(event)
            .map(MongoMappingEvent::getSource)
            .filter(ParentDocument.class::isInstance)
            .map(ParentDocument.class::cast)
            .ifPresent(parentDocument -> parentDocument.updated = LocalDateTime.now());

    Optional.ofNullable(event)
            .map(MongoMappingEvent::getSource)
            .filter(ChildDocument.class::isInstance)
            .map(ChildDocument.class::cast)
            .ifPresent(childDocument -> childDocument.updated = LocalDateTime.now());
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM