Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Collections are not created in new Mongo 2.6 #239

Closed
bogdanmt opened this Issue · 6 comments

2 participants

Bogdan Matei Jeremy Mikola
Bogdan Matei

You probably want a quick and concise email...

1) Mongo released this last Tue (April 8, 2014) the new version 2.6;

2) Your Symfony2 DoctrineMongoDBBundle FAILS to create collections when "app/console doctrine:mongodb:schema:create" or "app/console doctrine:mongodb:schema:update" are used.

3) The problem is caused by Mongo 2.6 which, for the collection creation command, does not allow anymore "size=null" and "max=null". Those two nulls have to be changed into numbers (zeros per default) or remove those properties from the command. The result is the same.

Currently, when a collection is created, your command definition is: { create: "SomeName", capped: null, size: null, max: null }

Mongo 2.6, because it wants numbers for "size" and "max", throws the error:

com.mongodb.CommandFailureException: { "serverUsed" : "localhost/127.0.0.1:27017" , "ok" : 0.0 , "errmsg" : "BadValue size has to be a number"}
at com.mongodb.CommandResult.getException(CommandResult.java:71)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:110)
at com.edgytech.umongo.DbJobCmd.doRun(DbJobCmd.java:56)
at com.edgytech.umongo.DbJob$1.doInBackground(DbJob.java:84)
at javax.swing.SwingWorker$1.call(SwingWorker.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at javax.swing.SwingWorker.run(SwingWorker.java:334)
at com.edgytech.swingfast.ScalableThreadPool$ScalableThreadpoolWorker.run(ScalableThreadPool.java:48)
at java.lang.Thread.run(Thread.java:744)

That's it. I hope you'll release a quick fix asap.

Anyway RESPECT FOR YOUR WORK!

Bogdan Matei

I found the root of the problem:

  • in this class, vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataInfo.php the properties $collectionSize ans $collectionMax remain uninitialized, thus "null". These parameters are passed to MongoDB createCollection and starting with Mongo 2.6 collection will fail, because Mongo database became restrictive by expeting integer only.

Of course the right fix would be that MongoDB createCollection function checks its params for being integer and not null, but until then, my fixes are (either one or both):
1) in vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataInfo.php => lines 162, 167, initialize $collectionSize and $collectionMax with zero
2) in vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/SchemaManager.php => 332-333, check that you pass numeric values for size and max, like
is_numeric($class->getCollectionSize()) ? $class->getCollectionSize() : 0,
is_numeric($class->getCollectionMax()) ? $class->getCollectionMax() : 0

My choice is solution 1, but I would like this fix to be done in MongoDB createCollection, there where the root is.

Jeremy Mikola
Owner

@bogdanmt: Can you quickly test if adding (integer) casts in Doctrine\MongoDB\Database::createCollection() would work? I think we can solve this a level below ODM.

public function createCollection($name, $cappedOrOptions = false, $size = 0, $max = 0)
{
    $options = is_array($cappedOrOptions)
        ? array_merge(array('capped' => false, 'size' => 0, 'max' => 0), $cappedOrOptions)
        : array('capped' => (boolean) $cappedOrOptions, 'size' => (int) $size, 'max' => (int) $max);

    // ...
}
Bogdan Matei

That was my first thought too, but actually it was not enough. At that time I didn't took a closer look why. The reason is the variable $cappedOrOptions, which comes as an array having keys "size" and "max" NULL. In this line of code it goes with the merge, thus overwriting the zeros and leaving NULL for those keys:
$options = is_array($cappedOrOptions)
? array_merge(array('capped' => false, 'size' => 0, 'max' => 0), $cappedOrOptions)
: array('capped' => $cappedOrOptions, 'size' => $size, 'max' => $max);

My fix, in order to cover both cases is to write immediatelly after:
if (!is_numeric($options['size'])) {
$options['size'] = 0;
}
if (!is_numeric($options['max'])) {
$options['max'] = 0;
}

This I tested and it works fine.

Bogdan Matei

Would be great to have an official fix, even below ODM. We could rely on composer install again.

Jeremy Mikola jmikola referenced this issue from a commit in doctrine/mongodb
Jeremy Mikola jmikola Cast createCollection() options for MongoDB 2.6 compatibility
MongoDB 2.6 complains if the size/max options are non-numeric (e.g. null). See: doctrine/DoctrineMongoDBBundle#239
c832bd2
Jeremy Mikola
Owner

Tagged doctrine/mongodb 1.1.6, which should address this.

Jeremy Mikola jmikola closed this
Bogdan Matei

I confirm it works. Good job!

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.