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)
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.
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
}