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

Broken ODM schema produces different results with and without schema caching #1271

Closed
pilou opened this issue Nov 9, 2015 · 6 comments
Closed

Comments

@pilou
Copy link

pilou commented Nov 9, 2015

On dev enviroment we don't use MetadataCache, but in production we do.
The problem is that the schema genereated from yaml files seems to be okay in dev, but fails on production.
The first request is okay when there is no cache yet, but when the schema is read from cache sometimes there are errors that are not experienced without caching.
By saying "using no cache" I mean either setting ArrayCache, or setting other caching methods like Filesystem cache or Mongodb cache but clearing all entries before running the script.

In the example below you can see a schema with inheritance, with some lines commented out.
I know that they are invalid without the commented lines, but it works when caching is not enabled.
When retrieving documents from DB without cache (even if I caching is on but empty), I get the correct hydrated objects, but when using caching, ODM tries to hydrate the document as Document\Font\Family (the superclass)

Document\Font\Family:
#  type: mappedSuperclass
#  inheritanceType: SINGLE_COLLECTION
  collection: FontFamily
  repositoryClass: Repository\Font\Family
  discriminatorField: _t
  discriminatorMap:
      system: Document\Font\Family\System
      google: Document\Font\Family\Google
      uploaded: Document\Font\Family\Uploaded
  fields:
    id:
      id: true
      strategy: AUTO
    name:
      type: string
      name: n
    wysiwygSafe:
      type: boolean
      name: ws

Document\Font\Family\Google:
  collection: FontFamily
#  inheritanceType: SINGLE_COLLECTION
  repositoryClass: Repository\Font\Family

Document\Font\Family\System:
  collection: FontFamily
#  inheritanceType: SINGLE_COLLECTION
  repositoryClass: Repository\Font\Family

Document\Font\Family\Uploaded:
  collection: FontFamily
#  inheritanceType: SINGLE_COLLECTION
  repositoryClass: Repository\Font\Family
  fields:
      md5:
          type: string
          name: md5

It is absolutely clear that the problem is with the missing attrbutes (inheritanceType, type: mappedSuperclass), but the sad thing is that we encounter the problem on production env only.

Is there a way that we validate the schema with a cli tool, or to make the caching system so that ODM produces the same results with and without caching (even if the schema is invalid)?

@malarzm
Copy link
Member

malarzm commented Nov 9, 2015

I suppose this could happen because of checks like this one - when metadata is built we're not strict and will set everything passed while for serialization we'll require certain conditions to be met to dump related properties.

Is there a way that we validate the schema with a cli tool, or to make the caching system so that ODM produces the same results with and without caching (even if the schema is invalid)?

If I'm not mistaken you could gather all metadata and check if $original == unserialize(serialize($original)) - should be quite easy to make a cli command for this

@malarzm malarzm added the Idea label Nov 9, 2015
@pilou
Copy link
Author

pilou commented Nov 10, 2015

Could you put me on the track how to do it? Im not familiar with the core fuctions, and its quite complex.

@malarzm
Copy link
Member

malarzm commented Nov 10, 2015

Take a look at

$metadatas = $dm->getMetadataFactory()->getAllMetadata();
as this fetches (and filters if you'd want to) all metadata, later you'll need to just iterate through it and apply check $original == unserialize(serialize($original)) - that should be all.

@pilou
Copy link
Author

pilou commented Nov 10, 2015

Thanks for pointing me to the right direction.

Here is the testing snippet:

function rrmdir($dir) { 
  if (is_dir($dir)) { 
    $objects = scandir($dir); 
    foreach ($objects as $object) { 
      if ($object != "." && $object != "..") { 
        if (is_dir($dir."/".$object))
          rrmdir($dir."/".$object);
        else
          unlink($dir."/".$object); 
      }
    }
    rmdir($dir); 
  }
}

$metadataFactory = $dm->getMetadataFactory();

$cacheDir = __DIR__ . '/tmp';
$cacheDriver = new FilesystemCache($cacheDir);
$metadataFactory->setCacheDriver($cacheDriver);
/* @var $metadataFactory Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory */

/*
 * Doesn't clean up empty dirs, so I delete the entire testing dir recursively
 * $metadataFactory->getCacheDriver()->deleteAll();
 * $metadataFactory->getCacheDriver()->flushAll();
*/
rrmdir($cacheDir);

$hasError = false;
$meta = $metadataFactory->getAllMetadata();
foreach ($meta as $metaItem) {
    if ($metaItem != unserialize(serialize($metaItem))) {
        echo $metaItem->name . " has schema issues\n";
        $hasError = true;
    }
}
if (!$hasError) {
    echo "No schema errors found\n";
}

I chose FilesystemCache because it has a small dependency.

If some needs more info about the diff this tool could be used https://github.com/sebastianbergmann/diff.

Thank you! I owe you a beer :)

@malarzm
Copy link
Member

malarzm commented Nov 10, 2015

Thank you! I owe you a beer :)

Looking forward ;)

Also if somebody would have time to pull this together as a command it would be cool.

@malarzm malarzm added the Has PR label Oct 25, 2016
@malarzm malarzm added this to the 1.2 milestone Dec 27, 2016
@malarzm
Copy link
Member

malarzm commented Dec 27, 2016

Closing as #1519 was merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants