有没有办法使用 Spring Data JPA 中的方法 save 更新实体对象的仅某些字段?
例如,我有一个这样的 JPA 实体:
@Entity
public class User {
@Id
private Long id;
@NotNull
private String login;
@Id
private String name;
// getter / setter
// ...
}
使用它的 CRUD repo :
public interface UserRepository extends CrudRepository<User, Long> { }
在 Spring MVC 中,我有一个 Controller ,它获取一个 User 对象来更新它:
@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {
// Assuming that user have its id and it is already stored in the database,
// and user.login is null since I don't want to change it,
// while user.name have the new value
// I would update only its name while the login value should keep the value
// in the database
userRepository.save(user);
// ...
}
我知道我可以使用 findOne 加载用户,然后更改其名称并使用 save 更新它...但是如果我有 100 个字段并且我想更新其中的 50 个,更改每个值可能会非常烦人..
有没有办法告诉类似“保存对象时跳过所有空值”?
最佳答案
我也有同样的问题,正如 M. Deinum 指出的那样,答案是否定的,你不能使用保存。主要问题是 Spring Data 不知道如何处理空值。 null值是没有设置还是因为需要删除才设置?
现在从你的问题来看,我想你也有和我一样的想法,那就是 save 可以让我避免手动设置所有更改的值。
那么有没有可能避免所有的手动映射呢?好吧,如果您选择遵守 null 始终表示“未设置”的约定并且您拥有原始模型 ID,那么可以。 您可以使用 Springs BeanUtils 自己避免任何映射。
您可以执行以下操作:
现在,Spring 的 BeanUtils 实际不支持不复制 null 值,因此它将覆盖现有模型对象上未设置为 null 的任何值。幸运的是,这里有一个解决方案:
How to ignore null values using springframework BeanUtils copyProperties?
所以把它们放在一起你最终会得到这样的东西
@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {
User existing = userRepository.read(user.getId());
copyNonNullProperties(user, existing);
userRepository.save(existing);
// ...
}
public static void copyNonNullProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
关于java - JPA:仅更新特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27818334/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/