问题:我有实体Document,它有很多列,一对一,一对多和多对多映射到其他一些实体。 例: 文献: ID, 标题, 身体, 作家, 观众, ...
使用REST,我想更新一些特定的文档,控制器接收序列化的Document对象,调用EntityManager的merge方法将null结果持久存储到数据库中,如果控制器仅接收到实体,那么我希望仅更新主体,但是合并删除标题,作者和观众等的记录。
我知道这是EntityManager的标准行为,但我想问的是,在没有从前端或其他端点接收整个实体的情况下,对实体进行更新的首选技术是什么。我应该使用我收到的ID从数据库加载实体,并手动设置所有字段,然后保存到数据库,或者我应该使用其他技术。
我手动编写所有setter来复制更改没有任何问题,但实体的大小非常大,关系很多。在这种情况下要求最佳实践。
我了解DTO,但在使用控制器和服务方法的实体时我想要替代方法。
也许我在问一些含糊不清的东西,但在贬低之前请评论......
答案 0 :(得分:2)
对于实体部分更新,您将需要使用条件api或jpql ...如果您使用的是没有条件更新的旧版本或旧的查询解析器,其中不允许使用jpql更新,则必须先从数据库中读取,更新然后再次插入....你也可以使用updatable=false
来创建仅在创建时设置的列(如CREATION_DATE),并且在hibernate中还有一个很好的功能叫@DynamicUpdate
#39;尝试但看起来很棒...它只更新修改后的字段(check Vlad's post here)...关于DTO DP,如果你想隐藏/修改一些数据,我可能总是需要使用它客户端无论您存储数据的方式如何......它总是一种分离问题的好方法(但是由于spring converters而导致域和DTO对象之间的映射难以解决
答案 1 :(得分:1)
有两个选项,一个是更新查询,它可以正常工作,但您可能会感觉到 你正在失去一些hibernate功能和简单的代码。否则你可以用Hibernate的方式来实现,如下所示
AuditorBean auditorBean = (AuditorBean) session.get(AuditorBean.class, AuditorBean.getId());
auditorBean.setFirstName("aa");
auditorBean.setLatName("bb");
auditorBean.setTrainLevel("ISO");
auditorBean.setAccessLevel(4);
在这里,您不应该调用saveOrUpdate()或merge()之类的任何方法。 对象附加了事务,因此对象在事务结束时自动刷新并提交。