Why does http PATCH reset double properties to 0 w

2019-09-11 12:12发布

问题:

When I do an http PATCH to this model to update the "bar" value it works as expected.

@Entity
@Table(name='Foo')
class Foo {
    @Id
    String id = UUID.randomUUID()    
    double bar
    String baz
}

If instead, I do a PATCH to that same endpoint but ONLY include baz (leaving bar out of the payload completely) the database and returned JSON show the bar value was set to 0

Does anyone know why a PATCH would update the double value without it being in the body?

I'm using the default stack that ships w/ spring-boot 1.1.6 at this time (including data-jpa/ security/ web)

回答1:

When you do a PATCH then the following happens:

  • An new instance of Foo is created
  • Foo is populated with all values that have been sent with the request
  • The Foo entity with the id provided by the URI is loaded
  • All properties that differ between the two objects are copied from the new Foo to the persisted Foo, unless the value is null in the new Foo.

As you have seen that rather simple algorithm is extremely problematic when it comes to primitive values or any default values. bar will always be 0 in a new Foo instance and will therefore be copied if the persisted value is not 0. The problem is much bigger then one might think. Imagine baz had a default value, like "".

Your answer already contains one possible workaround for primitives, but unfortunately you can't cover default values in general. IMHO it's a serious bug caused by laziness.



回答2:

For anyone who might follow it appears you need to use the capital Double instead of the lowercase double

@Entity
@Table(name='Foo')
class Foo {
    @Id
    String id = UUID.randomUUID()    
    Double bar
    String baz
}