Leonardo Castanheira
Leonardo Castanheira

Reputation: 171

OnBeforeSave gets called but nothing happens

I am trying to check if the object I am trying to persist already have a "owner" and if not I set the logged in user. This EventListener is working for any other field of Contact and it does set the user when I debug. The return of the MongoRepository save method contains the correct set user but when I look in the DB the user wasn't saved.

OwnedByUserMongoEventListener class

public void onBeforeSave(BeforeSaveEvent<Contact> event) {
    Contact source = event.getSource();
    ReflectionUtils.doWithFields(source.getClass(), new OwnedByUserCallback(source));
}

OwnedByUserCallback class

@Override
public void doWith(java.lang.reflect.Field field) throws IllegalArgumentException, IllegalAccessException {
    ReflectionUtils.makeAccessible(field);
    final Object fieldValue = field.get(getSource());
    if (field.isAnnotationPresent(OwnedByUser.class)) {
        if ( fieldValue == null ) {
            JwtUser principal = (JwtUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            User user = mongoOperations.findOne(Query.query(Criteria.where("username").is(principal.getUsername())), User.class);
            field.set(getSource(), user);
        }
    }

}

/

Contact extends Auditable {

    @Id
    private String id;

    @Indexed(unique=true,sparse=true)
    @NotNull
    private Long seqId;

    private BasicDBObject attributes = new BasicDBObject(new HashMap<>());

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getAttributes() {
        return attributes.toMap();
    }

    public void setAttributes(Map<String, Object> attributes) {
        this.attributes = new BasicDBObject(attributes);
    }

    public String toString() {
        return "ID: "+getId() +" Attributes: " + getAttributes();
    }

    public Long getSeqId() {
        return seqId;
    }

    public void setSeqId(Long seqId) {
        this.seqId = seqId;
    }

}



public abstract class Auditable {

    @CreatedDate
    private Date createdDate;

    @DBRef
    @CreatedBy
    private User createdBy;

    @DBRef
    @OwnedByUser
    private User owner;

    @LastModifiedDate
    private Date updatedDate;

    @DBRef
    @LastModifiedBy
    private User updatedBy;

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public User getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(User createdBy) {
        this.createdBy = createdBy;
    }

    public Date getUpdatedDate() {
        return updatedDate;
    }

    public void setUpdatedDate(Date updatedDate) {
        this.updatedDate = updatedDate;
    }

    public User getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(User updatedBy) {
        this.updatedBy = updatedBy;
    }

    public User getOwner() {
        return owner;
    }

    public void setOwner(User owner) {
        this.owner = owner;
    }

}

Upvotes: 5

Views: 1998

Answers (1)

Leonardo Castanheira
Leonardo Castanheira

Reputation: 171

I was trying to use OnBeforeSave and you cannot change properties after a MongoConverter has been called unless you change the event.getDBObject(). If you want to make changes using your class Object then you need to use OnBeforeConvert... I spent a lot of time tracking this because of the poor documentation...

Upvotes: 12

Related Questions