Skip to content

Embedded document without any properties is persisted as an empty array #523

Closed
vmattila opened this Issue Mar 7, 2013 · 5 comments

3 participants

@vmattila
vmattila commented Mar 7, 2013

Hi,

I just noticed some strange behavior with Embedded documents. In case there is @EmbedOne'd document with none of the fields set and none of them is set as nullable=true, it seems that Doctrine persists the @EmbedOne as an empty array.

{
    "embedded_document": [ ]
}

If I now set the embedded field property via the parent's getter:
$parentDocument->getEmbeddedDocument()->setField('some_value');

I can see that Doctrine tries to make a call {"$set": {"embedded_document.field" : "some_value"} } but apparently Mongo does not set the value because of the empty array.

I try to reproduce the whole issue in a test case soon.

@jmikola
Doctrine member
jmikola commented Mar 7, 2013

Thanks. I know we have code in place to ensure empty embedded documents are prepared as an object instead of an array (see PersistenceBuilder::prepareEmbeddedDocumentValue), but this might be an uncaught edge case. A test case will be very helpful in narrowing it down. Feel free to make it a functional bug report test named GH523.

@vmattila
vmattila commented Mar 7, 2013

At this point, I am a very unsure where the bug is. We get the empty arrays in the db in regular basis, but I just wrote a minimum test case that resembles our Document structure and the test case passes well. I can set originally empty embedded document field values after re-fetching the main document from the DB and everything goes smoothly.

But when I browse logs in our actual application environment (Symfony2), I can see that
$document->getEmbeddedDocument()->setField("New value"); $dm->flush($document); makes Doctrine to send a query like {"$set": {"embedded_document.field": "New value"}} to database. The database still stays in state {"embedded_document": [ ] }. I recently identified that none of other updates in the same query are persisted either.

As far as I do not work with any of the embedded document's fields, everything works. If I clone and reset the embedded_document property (before or after calling setField("New value") on it, the whole embedded document gets happily flushed to the database as it converts to query {"$set": {"embedded_document": {"field": "New value"} } }.

Very strange, but I try to keep you updated if I manage to narrow the cause down.

@jwage
Doctrine member
jwage commented Mar 8, 2013

What version of the odm are you using?

@vmattila
vmattila commented Mar 8, 2013

This is our composer.json configuration in the real environment.

    "doctrine/mongodb-odm-bundle": "3.0.0-beta3",
    "doctrine/mongodb-odm": "1.0.0-beta8",
    "doctrine/mongodb": "1.0.1",

The passing unit test I wrote was against latest master c2eed60 .

@vmattila
vmattila commented Dec 3, 2014

Actually this might be related somehow to the JIRA issue https://jira.mongodb.org/browse/PHP-172. I recently hit this error when the database was in state { "embedded_document": [ ] } and Doctrine tried to do a query { "$set": {"embedded_document.field": "Something"} }. Apparently this failed with "Can't append to array" exception from MongoDB.

I will close this issue now as it seems Doctrine works fine in this very issue.

@vmattila vmattila closed this Dec 3, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.