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

Read only entity is tracked in the unit of work, can be persisted #10

Closed
HeathNaylor opened this issue Oct 5, 2018 · 2 comments
Closed

Comments

@HeathNaylor
Copy link

HeathNaylor commented Oct 5, 2018

I set up a basic prototype to see if this package would help solve a problem I am working on.

The code I have is very basic:

bootstrap.php

<?php

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use steevanb\DoctrineReadOnlyHydrator\Hydrator\ReadOnlyHydrator;

require_once "vendor/autoload.php";

$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
$config->addCustomHydrationMode(ReadOnlyHydrator::HYDRATOR_NAME, ReadOnlyHydrator::class);

$conn = array(
    'driver' => 'pdo_sqlite',
    'path' => __DIR__ . '/db.sqlite',
);

// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);

index.php

<?php

use steevanb\DoctrineReadOnlyHydrator\Hydrator\ReadOnlyHydrator;

require_once "bootstrap.php";

$queryBuilder = $entityManager->createQueryBuilder('user');

/** @var User $object */
$object = $queryBuilder
    ->select('user')
    ->from('user', 'user')
    ->where('user.id = ?1')
    ->setParameter(1, 1)
    ->getQuery()->setHydrationMode(ReadOnlyHydrator::HYDRATOR_NAME)->getResult()[0];

$entityManager->clear();

$object->setName('ASDF');
$entityManager->merge($object);
$entityManager->flush();

echo 'done';

After I run getResult() through the query, my entity manager unit of work is in this state:
image

To test my theory, I clear the entity manager, mutate the read only entity, merge it back into the entity manager to flush it.

The result is an updated record with ASDF as a user name in the database.
image

composer.json

{
    "require": {
        "doctrine/orm": "2.5.6",
        "steevanb/doctrine-read-only-hydrator": "^2.2"
    },
    "autoload": {
        "psr-0": {"": "src/"}
    }
}
@steevanb
Copy link
Owner

steevanb commented Oct 5, 2018

That's normal : when you use QueryBuilder, UnitOfWork register all you show in your screen. But it doens't register the hydrated object, as it's the hydrator who do that.

If you don't want to insert / update read only hydrated entities, you need to manualy register steevanb\DoctrineReadOnlyHydrator\EventSubscriber\ReadOnlySubscriber in Doctrine EventManager, and you don't do that in your snippet.

That's automaticaly done with you use Symfony Bundle.

@HeathNaylor
Copy link
Author

I guess I am confused, on the readme it says

So, in case you don't need to modify your entity, you want to be really faster, or just retrieve data stored in your database, you can use SimpleObjectHydrator or ReadOnlyHydrator.

This hydrated entities can't be persisted / flushed, because they are not registered in UnitOfwork to be faster.

I ended up going a different route that did not use these hydrators, but my overall goal was to get a quickly hydrated entity out of the database without it being registered to the unit of work.

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

2 participants