0

I am doing an application in Symfony2 and using the doctrine mongodb odm bundle. I created a document with an id that has strategy=NONE, like (just a snippet):

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Id(strategy="NONE")
 * @var string
 */
private $id;

Later on while inserting, every time I specify the id before calling persist, upon checking the logs I find that an upsert was done instead of a batchInsert. After some googling, I ran into this link that confirmed to me that, this is in fact, the case by design.

My question therefore is: how can avoid the upsert from happening after I have specified the object's id?

Ps: I need this because with the upsert, doctrine mongodb odm will update in case it finds the id already there, yet I want it to see such as a duplicate and throw a MongoDuplicateKeyException.

1 Answers1

0

As you noticed ODM will upsert new document if its identifier is set during initial persist (or identifier is generated during prePersist event), here you can see relevant code in UnitOfWork. For the document to be inserted you need to change your document's ID strategy to CUSTOM and use your own generator, you can find some information about it by the end of this docs chapter.

malarzm
  • 2,831
  • 2
  • 15
  • 25
  • Thanks for your response; definitely feels like the direction I should take. My only problem now is that I can't seem to figure out how (in my ID generator that extends the `Doctrine\ODM\MongoDB\Id\AbstractIdGenerator`), to use the `$param` in the `setId($param)` call, within my eventual id. – paulatumwine May 16 '16 at 09:24
  • I'm not sure what `$param` are you refering to? Generally speaking your generator needs to return the ID, ODM will set it later to document in question. – malarzm May 16 '16 at 14:48
  • Thanks again [malarzm](http://stackoverflow.com/users/5982920/malarzm) for helping. By `$param` I mean the value I intend to set as the id of the `$object` before passing it to persist, like `persist($object)`. The setId call would be like `$object->setId($param)`, somewhere after `$object`'s instantiation, but before `persist($object)`. Is there a way I can access this value(of `$param`) within the generator? – paulatumwine May 16 '16 at 15:04
  • The generator is supposed to create your `$param` and return it, ODM will later set generated identifier in object ([this is relevant code in ODM](https://github.com/doctrine/mongodb-odm/blob/a4d5226bd7594d09db4dc2741895c185c021dffd/lib/Doctrine/ODM/MongoDB/UnitOfWork.php#L1080-L1084)) – malarzm May 16 '16 at 15:47
  • Ah, I see; so in such cases, it isn't necessary to call `setId()`. Which brings me to the question, what if I needed the id to contain, say, some sort of user input in that it can't always be statically generated from within the generator, any ideas on how I may be able to go ahead with such? – paulatumwine May 17 '16 at 14:37
  • You need to transfer required informations into the generator somehow. Quickest things that comes to my head is setting the user input in some property in document itself (property doesn't even need to be mapped). – malarzm May 17 '16 at 15:07