Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doctrine unable to update rows after a change of strategy for the _id field. #522

Closed
adurieux opened this issue Mar 6, 2013 · 5 comments

Comments

@adurieux
Copy link

adurieux commented Mar 6, 2013

Hi all,

After hours of bug tracking, I finally found out what was happening. I want to share here this bug for future reference.

Symptoms

I was using the Doctrine ODM to update some objects in a very classic way.

  • The ODM was able to retrieve the documents from the DB
  • Calling persist() and flush() was working fine
  • The operations were correctly added to the UnitOfWork.
  • A log was written by the Doctrine Logger
  • But still, no update was performed on the DB !

What happened

When I first configured my documents with annotations, for some reason, I decided to use the "INCREMENT" strategy. During 1 month, I thus created documents with an _id that was an integer.

At some point, I decided to migrate to the "AUTO" strategy. I changed the annotation in the class, and, from this point on, my _id fields were thus of type ObjectId.

Thus, there is a mismatch between what Doctrine retrieves from the DB (an integer for the oldest records), and what it expects (an ObjectId). When you try to persist such a buggy object, Doctrine generates an update query with a non-existing ObjectId that it somehow computes from this integer. Provided this ObjectId does not exist, the update query does not work, thus leaving the DB unchanged...

Is this a problem ?

I am still wondering if this is a bug or a feature. IMO, Doctrine should warn about inconsistencies between the Model and the Data in this case.

@jwage
Copy link
Member

jwage commented Mar 6, 2013

It sounds like you changed your model property without migrating the underlying data? If you change the type of your fields you need to either handle it somehow in the app layer or migrate all the old data.

@adurieux
Copy link
Author

adurieux commented Mar 8, 2013

Yes indeed. I just wanted to report that this kind of issue could happen perfectly silently.

@websirnik
Copy link

I also have a problem after changing Id strategy. I've changed from strategy="auto" to strategy="alnum"
Now I'm getting:

ContextErrorException: Notice: Object of class MongoId could not be converted to int in
.../vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Types/IntType.php line 38

What would be the best way to migrate the data? And why it is converting to Int and not to String?
cc: @jwage

@jmikola
Copy link
Member

jmikola commented Sep 5, 2013

@websirnik: To debug, you can check what $generatorType and $mapping['type'] are being picked up in ClassMetadataInfo::mapField for the _id field. Additionally, a backtrace of your exception would help.

A great way to perform this kind of data migration (and any where mapped types are changed) would be to query using the $type operator to find documents in the collection with unexpected types. From there, you can process them individually in a script, update them all at once using some update operators, etc.

@malarzm
Copy link
Member

malarzm commented Aug 19, 2015

We introduced sanity checks for wrong values passed as AUTO identifiers in #1190 wchich will warn developer about problems during persisting.

@malarzm malarzm closed this as completed Aug 19, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants