Project is using play framework 1.3.3 I have a such controller:
public static void save(Item item) {
if (item.id != null) { //It means that item is not new, it is being edited
Item existingOldItem = Item.findById(item.id);
//Here I should have an old version of an item as "existingOldItem"
//and new one coming from http request as "item"
}
But the problem is item and existingOldItem are very identical. Item.findById line doesn't return me an old item from database, but returns the new item from http request (the same with JPA.em().createQuery). I suppose play framework sends a new item in a cache, and findById returns the item from the cache, not from a database. Please, could someone explain me the logic behind it and the ways how to solve the problem.
the problem is item and existingOldItem are very identical. Item.findById line doesn't return me an old item from database
That's the expected behavior. Item.findById() is returning the old item, as modified by the HTTP client. Take a look at JPA object binding from the Play! documentation to see the calling pattern.
Please, could someone explain me the logic behind it...
In short, the HTTP client is expected to provide an ID of the item record and its new property values in the HTTP Request. Play! sets up the item
parameter ready to be saved, finding the item in the database and modifying its properties according to the POST parameters. So you shouldn't have an "old" and a "new" item, you should just have an
"item" object which may be old or new, depending upon whether or not the ID provided by the HTTP client was found
in the database. All your controller action has to do is to invoke item.save()
.
The magic is in JPAPlugin.bind
. As you guessed, it first looks for the object in the database.
If it finds the object, then it calls Item.edit()
using that object. This is also magic and the
default implementation sets all properties of Item for which there are matching HTTP parameters.
... and the ways how to solve the problem.
I'm not sure what you consider the problem to be, but if you want an old and a new item, then the client shouldn't provide an
item.id
parameter. If you don't like that Play! digs into your database to instantiate the item
parameter, then you can provide a custom
binder or have the controller action accept a similar-looking POJO class, instead of the JPA class.