我正在创建一个SpringBoot/Angular 8应用程序,并在尝试更新解耦的前端/后端对象时遇到一些问题。当我发送包含角模型的json post请求时,@JsonIgnore
'd或其他缺失的值将被更新为null,而不是被忽略。
这个堆栈溢出问题与此密切相关,推荐的解决方案确实有效,但它打断/绕过了一系列Jackson/Hibernate注释(例如@heritance(strategy=heritanceType.JOINED)
和@Transient
),所以,如果可能的话,我想寻找其他的解决方案:当使用json解析实体时,hibernate会部分更新
@Entity
@Table(name = "users")
@DynamicUpdate
public class User implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String a;
@Column
private String b;
@Column (nullable = false)
@JsonIgnore
private String c;
// standard getters and setters
}
@RequestMapping(value = "/api/user", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<User> saveOrUpdate(@RequestBody User user, BindingResult result, HttpServletRequest request) {
if(user.getId()!=null){
user=ws.update(user);
}else{
user=us.create(user);
}
return new ResponseEntity<>(user,HttpStatus.OK);
}
saveUser(user:User): Observable<User>{
const body = JSON.stringify(user);
return this.http.post<User>('/api/user', body).pipe(map( response => response));
}
{
id:1,
a:"some value a"
b:"some value b"
c:"some value c"
}
{
id:1,
a:"some value a2"
b:"some value b2"
}
更新用户集a=?,b=?其中id=
更新用户集a=?,b=?,c=?其中id=
C是一个空值。
我最终修改了现有的解决方案,并使用反射为有问题的注释添加了排除项。
此解决方案基本上只是从会话中提取现有模型,并跨会话复制所有非null属性。然后,上面提到的@DynamicUpdate属性确保只更新修改后的属性。
protected String[] getNullPropertyNames (T source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
boolean skipProperty;
for(java.beans.PropertyDescriptor pd : pds) {
skipProperty=false;
if(pd.getReadMethod()!=null) {
for (Annotation a : pd.getReadMethod().getAnnotations()) {
if (a.toString().equals("@javax.persistence.Transient()")) {/*Skip transient annotated properties*/
skipProperty = true;
}
}
}else{
skipProperty=true;
}
if(!skipProperty){
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
// then use Spring BeanUtils to copy and ignore null
public void copyUpdatedProperties(T newEntity, T existingEntity) {
BeanUtils.copyProperties(newEntity, existingEntity, getNullPropertyNames(newEntity));
}
这解决了我所有的直接问题,但是我怀疑注释@In的继承(策略=继承类型。JOINED)
可能会在以后导致问题。
我没有尝试过这一点,但是设置dynamicUpdate=true应该可以完成这项工作。(如果您不知道将更改哪些属性,这可能是唯一的干净选项,因为前端只发送更改的属性)。请遵循本教程并让我知道它是否正常工作:Hibernate–动态更新属性示例
不要对从角发送的对象使用更新方法,因为它替换了数据库中的整个原始对象。在更新的情况下,我建议你从数据库中检索存在的对象(例如,使用Spring数据存储库findOne方法),然后只复制修改过的字段,忽略空值。您可以使用Apache共享库中的BeanUtils复制属性方法。原始方法在复制时不会忽略空值,因此您必须稍微重写它:
public class NullAwareBeanUtilsBean extends BeanUtilsBean {
@Override
public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException {
if (value == null)
return;
super.copyProperty(dest, name, value);
}
}
这个测试再现了你想要做的事情:
要更新的类:
public class A {
private String foo;
private String bar;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
测试等级:
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.zpavel.utils.NullAwareBeanUtilsBean;
public class MyTest {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
A a1 = new A();
a1.setFoo("foo");
A a2 = new A();
a2.setBar("bar");
BeanUtilsBean notNull = new NullAwareBeanUtilsBean();
notNull.copyProperties(a2, a1);
System.out.println(ToStringBuilder.reflectionToString(a2));
}
}
我正在使用Spring Data MongoDB和Spring Data Rest创建一个Rest API,它允许对我的MongoDB数据库进行GET、POST、PUT和DELETE操作,除了更新操作(PUT)之外,其他操作都很好。只有当我在请求体中发送完整的对象时,它才起作用,否则变量没有在rquest中发送它,则为NULL。有人能指导我解决这个问题吗。
下面是我的JSON: 我想用下面的规则更新上述JSON字符串的两个属性: 标志:我想盲目地将此属性更新为。 infoFlag:如果< code>info的< code>name属性为< code>null,那么我希望将< code>infoFlag更新为< code>true否则为< code>false,如果它为< code>not null。 因此,在用这些规则更新JSON之后,我希望将JSO
Hibernate的property元素具有update、insert属性,根据文档,它声明-http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/mapping.html#mapping-声明属性 update,insert(可选-默认为true):指定映射列应包含在SQL update和/或insert语句中。将两者都设置为f
我已经扩展了TreeCell和TreeItem类。MyTreeItem包含一个自定义属性,我在MyTreeCell中使用它来渲染图形/字体等。问题是当我设置MyTreeCell.custom属性我不知道如何使TreeView/单元格重绘。 例如: 任何关于解决方案或(缺乏)设计方法的意见都受到赞赏。
在几个表中有几列数据库列定义从实体中的声明更改。喜欢 和 mycolumn' bigint(20) not null默认值为0 在 MySQL 中。 为什么hbm2ddl不更新这样的东西?有可能强制这样的更新吗?我想说hbm2ddl删除列的默认值并更改类型的长度。
是否可以通过KeyClope REST API更新自定义属性的值?例如,要使用哪个endpoint,以及如何为此处创建的属性构造请求主体。 谢谢