使SpringData仅更新POJO的更改字段

ain*_*cat 7 java spring mongodb spring-data spring-data-mongodb

我在MongoDB上使用Spring Data。我能够保存POJO,对其进行更新。一切正常。但是现在我想在db中仅刷新POJO的更改字段。

例如,我有用户实体。我创建用户,然后不时更新lastActiveDate。

@Document
class User {
    @Id
    BigInteger ID;

    String email;

    String name;

    Date lastActiveDate;
}

User user = new User();
user.setName("User");
user.setEmail("example@example.com");
repository.save(user);

User toUpdUser = repository.findOne(userId);
toUpdUser.setLastActiveDate(new Date);
repository.save(toUpdUser );
Run Code Online (Sandbox Code Playgroud)

在第二次保存中,我只想更新lastActiveDate字段而不是整个用户,因为大型实体上的文档更新可能很慢。我也想知道changeset(至少是一组更新字段)。

目前,我没有找到执行此操作的API。唯一的可能是在设置器中手动处理它(存储更改的字段集并手动存储),但是它看起来很丑陋且不被支持。另一个选择是在bean上使用AOP来达到相同的结果,但是IFAIK Spring Data不会将POJO视为Spring bean,而是使用构造函数,因此在用AOP加载POJO之后将只是POJO。

UPD:我正在寻找没有显式mongo api(或类似mongo的api)调用的方法。我的实体拥有数十个领域,客户几乎可以更改其中任何一个。我只想存储更改的字段,并能够获取更改集以执行一些检查。实体存储与字段更新之间的差异过大-5ms与0.2ms

当然,我可以使用CRUD跟踪器支持创建自己的POJO映射器实现,但是已经存在,为什么不尝试一下。而且我不仅可以使用SpringData,还可以使用其他框架。

gog*_*tad 5

Spring-data不支持逐字段比较,以找出要更新的字段,而仅将其发送到数据库。但是,它确实仅支持持久的非null字段,我发现自己在实现PATCHPUTWeb服务时会充分利用这一点。$set使用非空字段创建一个对象,然后将文档的另一部分保持不变。

您将需要使用的某种未记录的功能MongoConverters,这是PATCH-webservice 的示例,在该示例中spring-mvc,还可以在文档的“事件”数组中维护事件的历史记录:

@RestController
public class MyWebservice {

    @Autowired
    private MongoConverter mongoConverter;

    @RequestMapping(value = "/order/{id}", method = PATCH, produces = APPLICATION_JSON_UTF8_VALUE, consumes = APPLICATION_JSON_UTF8_VALUE)
    public Order updateOrder(@PathVariable("id") String id, @RequestBody Order order) throws JsonProcessingException {
        order.setId(id);
        DBObject update = getDbObject(order);
        mongoTemplate.updateFirst(query(where("id").is(id)), Update.fromDBObject(new BasicDBObject("$set", update)).push("events", order), Order.class);
        return mongoTemplate.findOne(query(where("id").is(id)), Order.class);
    }

    private DBObject getDbObject(Object o) {
        BasicDBObject basicDBObject = new BasicDBObject();
        mongoConverter.write(o, basicDBObject);
        return basicDBObject;
    }
}
Run Code Online (Sandbox Code Playgroud)

MongoConverter只会将非null值写入BasicDBObject


Nes*_*don 0

您正在寻找MongoTemplate.updateFirst()

请参阅此处的相关答案:Spring Data Mongodb:更新文档