Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persisting Doctrine entities with associations which have been deserialized with JMSSerializer

After successfully deserializing a json string to a Doctrine Entity with associations. When persisting, Doctrine detects these associations as "new entities" always. How can I update the associations just by the ID, and not changing the related entity values if there are any changes?

My case:

I have some database tables with static data. The simplest one is for storing Units. (I have a doctrine entity called Unit). The table is like this:

|id|name |ratio    |
|1 |mgr  |1      |
|2 |gr   |1000   |
|3 |Kgr  |1000000|

Then, the user can create an Item, which also has a server side doctrine entity called Unit. I use a client side backbone.js model and when updated it's sent to my Symfony2 app like this:

//Item object to be serialized into Item entity
{
  id:   13141
  weight: 100
  unit: {
      id:1
      name:mgr
      ratio:1
  }
  //many more attributes here
}

Now, I deserialize with JMSSerializer, everything is okay, but I want doctrine to update only the Unit ID of the relation, and not the whole Unit.

When I persist, doctrine complains and tells me that he found a "new Unit entity" (which is not what I want) and tells me to set cascade to persist in the doctrine Entity. But if I do this and someone modifies unit json, wouldn't that change my static Units table?

For example: Bad user modifies the Json by sending this:

//BAD item object to be serialized into Item entity
{
  id:   13141
  weight: 100
  unit: {
      id:1
      name:BadName //Will this get persisted to the database?
      ratio:1
  }
  //many more attributes here
}

I certainly don't want this to happen. I just want to add the Unit with id:1 to the item.

This case is simple, and I could just fetch the unit by Id and then set it to the entity, but in my real app the Item entity is much bigger so I want to handle this automatically.

¿Any Ideas?

like image 884
JMerino Avatar asked Jul 23 '13 17:07

JMerino


1 Answers

Let me get this straight:

When you deserialize text what is the type of unit member? is it class instance of just array?

If I understood correctly and it is class instance, you could set cascade to merge (not persist) on unit property so you could do:

$em = ...; // your entity manager
$item = $em->merge($item); // merge will cascade to `unit` property as well

Hope this helps...

like image 55
Jovan Perovic Avatar answered Oct 13 '22 21:10

Jovan Perovic