I'm updating a record from a form over AJAX. I have a JSON object that maps to my entity, and my controller method is:
@RequestMapping(value = "/vendors", method = RequestMethod.POST)
public ResponseEntity<String> saveVendorsJson(@RequestParam String vendor) {
Vendor v = Vendor.fromJsonToVendor(vendor);
if (v.merge() == null) {
v.persist();
}
return new ResponseEntity<String>(HttpStatus.OK);
}
I expected from the documentation that v.merge() will return null if it didn't find an existing record by the object's 'id' field to merge with, and in that case I want to persist it as a new Vendor object.
What's happening is, despite my JSON having an 'id' field value that matches an existing record, I'm ALWAYS inserting a new record with my updated goods from the browser.
I'm aware I'm having the POST method pull double-duty here, which isn't strictly RESTful. In theory, this is simpler for me (though of course that's turning out not to be the case).
I believe this is a Hibernate thing. Hibernate will not "merge" if it doesn't know it already exists. I think what I have done in the past is to do a lookup, then a persist. I think if you try to just merge something coming in off the wire you would get a Primary Key Collision, or something similar. I believe Hibernate has some sort of "dirty" flag internal to indicate if you are creating or editing an existing object.
There also used to be a way in raw-Hibernate to do a soft-lookup, basically tell Hibernate "look, I have this object, I don't want to do a SELECT blah-blah-blah, I just want to update some fields". It would load the object into Cache and allow you to do the update without doing the SELECT first. There is also an updateOrSave() in Spring, but that actually does the SELECT first.