首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用spring数据jpa只更新模型中的传入字段?

如何使用spring数据jpa只更新模型中的传入字段?
EN

Stack Overflow用户
提问于 2018-05-30 12:25:36
回答 4查看 2.7K关注 0票数 6

我使用Spring进行持久化。我得更新一下模型。该模型有“n”个字段和一个主键。

代码语言:javascript
运行
复制
    {
    "some_model":{
        "id":"5527716",
        "field_one": "44248156",
        "field_two": "44248156",
        "field_three": "44248156",
        "field_four": "44248156",
        "field_five": "44248156",
        "field_six": "44248156",
        "field_seven": "44248156",
        "field_eight": "44248156",
        "field_nine":"65037768"     
    }
}

考虑到上面json作为我的模型的一个表示,我只想更新那些传入json中的字段(主键是Id,它将始终在那里)。是否有任何方法可以实现,而不必显式地检查每个字段并设置它们?

如果我收到这样的请求:

代码语言:javascript
运行
复制
{
    "some_model":{
        "id":"5527716",
        "field_one": "44248156",
        "field_two": "44248156",
        "field_three": "44248156",

        "field_eight": "44248156",
        "field_nine":"65037768"     
    }
}

我只想使用repository.save或类似的东西来实现更新(插入类的东西)。目前,使用存储库的保存方法在内部使用primaryKey值更新模型,但将缺失字段的值设置为null。我希望这些字段保持不变。

主要问题是:有数百个模型,每个模型大约有10-15个字段,显式检查每个字段并更新所有模型将是一场噩梦。

我还检查了@DynamicUpdate注释,但它似乎适用于优化生成的sql的显式设置。

我希望对此有任何想法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-06-29 05:05:16

我发现我的问题的确切要求不能得到满足。Dozer Bean Mapper似乎是一个选项,但更多的是映射不同类的bean对象,在那里我们可以对应要映射的字段,这不是我的情况。

解决方案是改变在执行更新时发送所有所需信息的方法。

正如西蒙在评论中指出的:

简单的回答:那是不可能的。因为反序列化之后,如果字段丢失,则值为null。Java是一种静态类型化语言,不能很好地满足您的要求。

票数 0
EN

Stack Overflow用户

发布于 2018-05-30 12:48:41

通常,合并将对您有效,因为您得到了独立的副本--从JSON获得的副本和持久化的副本(来自存储库)。Merge正是这样做的--用分离的属性的值更新持久化属性,如果没有值,它就创建它(我不确定该部分是否需要)。仍然是自动的,你失去了你自己写它的灵活性。

对于JPA,合并方法是EntityManager的一部分。因此,您需要注入它并将其称为em.merge(detachedEntity);

除此之外,还有一些库可以这样做,但我没有使用任何库。需要进行一些编码的最佳解决方案是编写手动更新字段的方法;)

票数 4
EN

Stack Overflow用户

发布于 2018-05-30 12:45:11

看看杜泽尔 --一个bean映射库。您可以使用自定义字段映射器配置dozer,如果字段为null,则不复制字段。

您可以从DB检索对象,将字段值从请求对象复制到从DB检索的对象(使用不映射空值的自定义字段映射程序),然后保存对象。

代码语言:javascript
运行
复制
    User user1 = new User(); // Request body
    user1.setFirstName("newFn");

    User user2 = new User(); // Entity retrieved from the database
    user2.setFirstName("fn");
    user2.setLastName("ln");

    DozerBeanMapper dozerBeanMapper = new DozerBeanMapper();
    dozerBeanMapper.setCustomFieldMapper(
            (source, destination, sourceFieldValue, classMap, fieldMapping) -> sourceFieldValue == null);
    dozerBeanMapper.map(user1, user2);
    System.out.println(user2); // User(firstName=newFn, lastName=ln)

参考文献:https://stackoverflow.com/a/36716023/1377058

如果不希望将dozer作为依赖项添加,还可以使用BeanUtils只复制那些非空属性。看看的问题,了解如何做它的细节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50604647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档