[2.0] Fixed #2366.
This commit is contained in:
parent
be0088f00c
commit
ae1b9371ec
@ -413,13 +413,12 @@ class EntityManager
|
|||||||
* Refreshes the persistent state of an entity from the database,
|
* Refreshes the persistent state of an entity from the database,
|
||||||
* overriding any local changes that have not yet been persisted.
|
* overriding any local changes that have not yet been persisted.
|
||||||
*
|
*
|
||||||
* @param object $entity
|
* @param object $entity The entity to refresh.
|
||||||
* @todo Implementation
|
|
||||||
*/
|
*/
|
||||||
public function refresh($entity)
|
public function refresh($entity)
|
||||||
{
|
{
|
||||||
$this->_errorIfClosed();
|
$this->_errorIfClosed();
|
||||||
throw DoctrineException::notImplemented();
|
$this->_unitOfWork->refresh($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -260,7 +260,7 @@ class ObjectHydrator extends AbstractHydrator
|
|||||||
} else {
|
} else {
|
||||||
// Eager load
|
// Eager load
|
||||||
//TODO: Allow more efficient and configurable batching of these loads
|
//TODO: Allow more efficient and configurable batching of these loads
|
||||||
$assoc->load($entity, new $className, $this->_em, $joinColumns);
|
$assoc->load($entity, new $assoc->targetEntityName, $this->_em, $joinColumns);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//TODO: Eager load
|
//TODO: Eager load
|
||||||
|
@ -37,8 +37,18 @@ namespace Doctrine\ORM\Mapping;
|
|||||||
*/
|
*/
|
||||||
abstract class AssociationMapping
|
abstract class AssociationMapping
|
||||||
{
|
{
|
||||||
const FETCH_MANUAL = 1;
|
/**
|
||||||
|
* Specifies that an association is to be fetched when it is first accessed.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
const FETCH_LAZY = 2;
|
const FETCH_LAZY = 2;
|
||||||
|
/**
|
||||||
|
* Specifies that an association is to be fetched when the owner of the
|
||||||
|
* association is fetched.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
const FETCH_EAGER = 3;
|
const FETCH_EAGER = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +76,7 @@ abstract class AssociationMapping
|
|||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
public $fetchMode = self::FETCH_MANUAL;
|
public $fetchMode = self::FETCH_LAZY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that indicates whether the class that defines this mapping is
|
* Flag that indicates whether the class that defines this mapping is
|
||||||
@ -244,16 +254,6 @@ abstract class AssociationMapping
|
|||||||
return $this->fetchMode == self::FETCH_LAZY;
|
return $this->fetchMode == self::FETCH_LAZY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the target entity/entities of the association are manually fetched.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function isManuallyFetched()
|
|
||||||
{
|
|
||||||
return $this->fetchMode == self::FETCH_MANUAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the source entity of this association represents the owning side.
|
* Whether the source entity of this association represents the owning side.
|
||||||
*
|
*
|
||||||
|
@ -198,7 +198,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||||||
public function remove($key)
|
public function remove($key)
|
||||||
{
|
{
|
||||||
//TODO: delete entity if shouldDeleteOrphans
|
//TODO: delete entity if shouldDeleteOrphans
|
||||||
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans()) {
|
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans) {
|
||||||
$this->_em->remove($removed);
|
$this->_em->remove($removed);
|
||||||
}*/
|
}*/
|
||||||
$removed = parent::remove($key);
|
$removed = parent::remove($key);
|
||||||
@ -209,8 +209,8 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the collection is a Map this is like put(key,value)/add(key,value).
|
* When the collection is used as a Map this is like put(key,value)/add(key,value).
|
||||||
* When the collection is a List this is like add(position,value).
|
* When the collection is used as a List this is like add(position,value).
|
||||||
*
|
*
|
||||||
* @param integer $key
|
* @param integer $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
@ -302,6 +302,9 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the collection by loading its contents from the database.
|
||||||
|
*/
|
||||||
private function _initialize()
|
private function _initialize()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -375,15 +378,21 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||||||
{
|
{
|
||||||
//TODO: Register collection as dirty with the UoW if necessary
|
//TODO: Register collection as dirty with the UoW if necessary
|
||||||
//TODO: If oneToMany() && shouldDeleteOrphan() delete entities
|
//TODO: If oneToMany() && shouldDeleteOrphan() delete entities
|
||||||
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans()) {
|
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans) {
|
||||||
foreach ($this->_data as $entity) {
|
foreach ($this->_data as $entity) {
|
||||||
$this->_em->remove($entity);
|
$this->_em->remove($entity);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
parent::clear();
|
parent::clear();
|
||||||
|
if ($this->_association->isOwningSide) {
|
||||||
$this->_changed();
|
$this->_changed();
|
||||||
|
$this->_em->getUnitOfWork()->scheduleCollectionDeletion($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks this collection as changed/dirty.
|
||||||
|
*/
|
||||||
private function _changed()
|
private function _changed()
|
||||||
{
|
{
|
||||||
$this->_isDirty = true;
|
$this->_isDirty = true;
|
||||||
|
@ -25,6 +25,7 @@ namespace Doctrine\ORM\Persisters;
|
|||||||
* Persister for collections of basic elements / value types.
|
* Persister for collections of basic elements / value types.
|
||||||
*
|
*
|
||||||
* @author robo
|
* @author robo
|
||||||
|
* @todo Implementation once support for collections of basic elements (i.e. strings) is added.
|
||||||
*/
|
*/
|
||||||
class ElementCollectionPersister extends AbstractCollectionPersister
|
class ElementCollectionPersister extends AbstractCollectionPersister
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||||||
$mapping = $coll->getMapping();
|
$mapping = $coll->getMapping();
|
||||||
$joinTable = $mapping->getJoinTable();
|
$joinTable = $mapping->getJoinTable();
|
||||||
$whereClause = '';
|
$whereClause = '';
|
||||||
foreach ($mapping->getSourceToRelationKeyColumns() as $relationColumn) {
|
foreach ($mapping->sourceToRelationKeyColumns as $relationColumn) {
|
||||||
if ($whereClause !== '') $whereClause .= ' AND ';
|
if ($whereClause !== '') $whereClause .= ' AND ';
|
||||||
$whereClause .= "$relationColumn = ?";
|
$whereClause .= "$relationColumn = ?";
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,23 @@ use Doctrine\ORM\PersistentCollection;
|
|||||||
/**
|
/**
|
||||||
* Persister for one-to-many collections.
|
* Persister for one-to-many collections.
|
||||||
*
|
*
|
||||||
* This persister is only used for uni-directional one-to-many mappings.
|
* IMPORTANT:
|
||||||
|
* This persister is only used for uni-directional one-to-many mappings on a foreign key
|
||||||
|
* (which are not yet supported). So currently this persister is not used.
|
||||||
*
|
*
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
|
* @todo Complete implementation when the support for uni-directional one-to-many mappings
|
||||||
|
* on a foreign key gets added.
|
||||||
*/
|
*/
|
||||||
class OneToManyPersister extends AbstractCollectionPersister
|
class OneToManyPersister extends AbstractCollectionPersister
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* Generates the SQL UPDATE that updates a particular row's foreign
|
||||||
|
* key to null.
|
||||||
*
|
*
|
||||||
* @param <type> $coll
|
* @param PersistentCollection $coll
|
||||||
* @return <type>
|
* @return string
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||||
@ -63,14 +68,53 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||||||
return array("UPDATE $table SET $setClause WHERE $whereClause", $this->_uow->getEntityIdentifier($element));
|
return array("UPDATE $table SET $setClause WHERE $whereClause", $this->_uow->getEntityIdentifier($element));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _getInsertRowSql()
|
protected function _getInsertRowSql(PersistentCollection $coll)
|
||||||
{
|
{
|
||||||
return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
|
return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not used for OneToManyPersister */
|
/* Not used for OneToManyPersister */
|
||||||
protected function _getUpdateRowSql()
|
protected function _getUpdateRowSql(PersistentCollection $coll)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the SQL UPDATE that updates all the foreign keys to null.
|
||||||
|
*
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
*/
|
||||||
|
protected function _getDeleteSql(PersistentCollection $coll)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL parameters for the corresponding SQL statement to delete
|
||||||
|
* the given collection.
|
||||||
|
*
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
*/
|
||||||
|
protected function _getDeleteSqlParameters(PersistentCollection $coll)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL parameters for the corresponding SQL statement to insert the given
|
||||||
|
* element of the given collection into the database.
|
||||||
|
*
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
* @param mixed $element
|
||||||
|
*/
|
||||||
|
protected function _getInsertRowSqlParameters(PersistentCollection $coll, $element)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL parameters for the corresponding SQL statement to delete the given
|
||||||
|
* element from the given collection.
|
||||||
|
*
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
* @param mixed $element
|
||||||
|
*/
|
||||||
|
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element)
|
||||||
|
{}
|
||||||
}
|
}
|
@ -70,13 +70,6 @@ class StandardEntityPersister
|
|||||||
*/
|
*/
|
||||||
protected $_em;
|
protected $_em;
|
||||||
|
|
||||||
/**
|
|
||||||
* The EventManager instance.
|
|
||||||
*
|
|
||||||
* @var Doctrine\Common\EventManager
|
|
||||||
*/
|
|
||||||
protected $_evm;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queued inserts.
|
* Queued inserts.
|
||||||
*
|
*
|
||||||
@ -96,7 +89,6 @@ class StandardEntityPersister
|
|||||||
{
|
{
|
||||||
$this->_em = $em;
|
$this->_em = $em;
|
||||||
$this->_platform = $em->getConnection()->getDatabasePlatform();
|
$this->_platform = $em->getConnection()->getDatabasePlatform();
|
||||||
$this->_evm = $em->getEventManager();
|
|
||||||
$this->_entityName = $class->name;
|
$this->_entityName = $class->name;
|
||||||
$this->_conn = $em->getConnection();
|
$this->_conn = $em->getConnection();
|
||||||
$this->_class = $class;
|
$this->_class = $class;
|
||||||
@ -206,17 +198,9 @@ class StandardEntityPersister
|
|||||||
);
|
);
|
||||||
$tableName = $this->_class->primaryTable['name'];
|
$tableName = $this->_class->primaryTable['name'];
|
||||||
|
|
||||||
if ($this->_evm->hasListeners(Events::preUpdate)) {
|
|
||||||
$this->_preUpdate($entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($updateData[$tableName]) && $updateData[$tableName]) {
|
if (isset($updateData[$tableName]) && $updateData[$tableName]) {
|
||||||
$this->_doUpdate($entity, $tableName, $updateData[$tableName], $id);
|
$this->_doUpdate($entity, $tableName, $updateData[$tableName], $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->_evm->hasListeners(Events::postUpdate)) {
|
|
||||||
$this->_postUpdate($entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -458,7 +442,9 @@ class StandardEntityPersister
|
|||||||
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnValues);
|
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnValues);
|
||||||
$this->_class->reflFields[$field]->setValue($entity, $proxy);
|
$this->_class->reflFields[$field]->setValue($entity, $proxy);
|
||||||
} else {
|
} else {
|
||||||
//TODO: Eager fetch
|
// Eager load
|
||||||
|
//TODO: Allow more efficient and configurable batching of these loads
|
||||||
|
$assoc->load($entity, new $assoc->targetEntityName, $this->_em, $joinColumnValues);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Inject collection
|
// Inject collection
|
||||||
|
@ -1310,6 +1310,71 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
return $managedCopy;
|
return $managedCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param $entity
|
||||||
|
* @return unknown_type
|
||||||
|
*/
|
||||||
|
public function refresh($entity)
|
||||||
|
{
|
||||||
|
$visited = array();
|
||||||
|
return $this->_doRefresh($entity, $visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a refresh operation on an entity.
|
||||||
|
*
|
||||||
|
* @param object $entity The entity to refresh.
|
||||||
|
* @param array $visited The already visited entities during cascades.
|
||||||
|
*/
|
||||||
|
private function _doRefresh($entity, array &$visited)
|
||||||
|
{
|
||||||
|
$oid = spl_object_hash($entity);
|
||||||
|
if (isset($visited[$oid])) {
|
||||||
|
return; // Prevent infinite recursion
|
||||||
|
}
|
||||||
|
|
||||||
|
$visited[$oid] = $entity; // mark visited
|
||||||
|
|
||||||
|
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||||
|
switch ($this->getEntityState($entity)) {
|
||||||
|
case self::STATE_MANAGED:
|
||||||
|
$this->getEntityPersister($class->name)->load(
|
||||||
|
array_combine($class->identifier, $this->_entityIdentifiers[$oid]),
|
||||||
|
$entity
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw DoctrineException::updateMe("NEW, REMOVED or DETACHED entity can not be refreshed.");
|
||||||
|
}
|
||||||
|
$this->_cascadeRefresh($entity, $visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cascades a refresh operation to associated entities.
|
||||||
|
*
|
||||||
|
* @param object $entity
|
||||||
|
* @param array $visited
|
||||||
|
*/
|
||||||
|
private function _cascadeRefresh($entity, array &$visited)
|
||||||
|
{
|
||||||
|
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||||
|
foreach ($class->associationMappings as $assocMapping) {
|
||||||
|
if ( ! $assocMapping->isCascadeRefresh) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$relatedEntities = $class->reflFields[$assocMapping->sourceFieldName]->getValue($entity);
|
||||||
|
if ($relatedEntities instanceof Collection) {
|
||||||
|
foreach ($relatedEntities as $relatedEntity) {
|
||||||
|
$this->_doRefresh($relatedEntity, $visited);
|
||||||
|
}
|
||||||
|
} else if ($relatedEntities !== null) {
|
||||||
|
$this->_doRefresh($relatedEntities, $visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cascades a merge operation to associated entities.
|
* Cascades a merge operation to associated entities.
|
||||||
*
|
*
|
||||||
@ -1324,7 +1389,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
if ( ! $assocMapping->isCascadeMerge) {
|
if ( ! $assocMapping->isCascadeMerge) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$relatedEntities = $class->reflFields[$assocMapping->getSourceFieldName()]
|
$relatedEntities = $class->reflFields[$assocMapping->sourceFieldName]
|
||||||
->getValue($entity);
|
->getValue($entity);
|
||||||
if ($relatedEntities instanceof Collection) {
|
if ($relatedEntities instanceof Collection) {
|
||||||
foreach ($relatedEntities as $relatedEntity) {
|
foreach ($relatedEntities as $relatedEntity) {
|
||||||
|
@ -173,8 +173,8 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
array())->fetchColumn();
|
array())->fetchColumn();
|
||||||
$this->assertEquals(10, $count);
|
$this->assertEquals(10, $count);
|
||||||
|
|
||||||
//$user->groups->clear();
|
$user->groups->clear();
|
||||||
unset($user->groups);
|
//unset($user->groups);
|
||||||
|
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
|
|
||||||
@ -184,6 +184,35 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals(0, $count);
|
$this->assertEquals(0, $count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOT YET IMPLEMENTED
|
||||||
|
public function testOneToManyOrphanDelete()
|
||||||
|
{
|
||||||
|
$user = new CmsUser;
|
||||||
|
$user->name = 'Guilherme';
|
||||||
|
$user->username = 'gblanco';
|
||||||
|
$user->status = 'developer';
|
||||||
|
|
||||||
|
for ($i=0; $i<3; ++$i) {
|
||||||
|
$phone = new CmsPhonenumber;
|
||||||
|
$phone->phonenumber = 100 + $i;
|
||||||
|
$user->addPhonenumber($phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_em->persist($user);
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
$user->getPhonenumbers()->remove(0);
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
// Check that the links in the association table have been deleted
|
||||||
|
$count = $this->_em->getConnection()->execute("SELECT COUNT(*) FROM cms_phonenumbers",
|
||||||
|
array())->fetchColumn();
|
||||||
|
$this->assertEquals(2, $count); // only 2 remaining
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
public function testBasicQuery()
|
public function testBasicQuery()
|
||||||
{
|
{
|
||||||
$user = new CmsUser;
|
$user = new CmsUser;
|
||||||
@ -304,4 +333,21 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$query = $this->_em->createQuery("select u, g from Doctrine\Tests\Models\CMS\CmsUser u inner join u.groups g");
|
$query = $this->_em->createQuery("select u, g from Doctrine\Tests\Models\CMS\CmsUser u inner join u.groups g");
|
||||||
$this->assertEquals(0, count($query->getResultList()));
|
$this->assertEquals(0, count($query->getResultList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBasicRefresh()
|
||||||
|
{
|
||||||
|
$user = new CmsUser;
|
||||||
|
$user->name = 'Guilherme';
|
||||||
|
$user->username = 'gblanco';
|
||||||
|
$user->status = 'developer';
|
||||||
|
|
||||||
|
$this->_em->persist($user);
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
$user->status = 'mascot';
|
||||||
|
|
||||||
|
$this->assertEquals('mascot', $user->status);
|
||||||
|
$this->_em->refresh($user);
|
||||||
|
$this->assertEquals('developer', $user->status);
|
||||||
|
}
|
||||||
}
|
}
|
@ -83,7 +83,7 @@ class OneToOneBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctional
|
|||||||
$this->_createFixture();
|
$this->_createFixture();
|
||||||
$this->_em->getConfiguration()->setAllowPartialObjects(false);
|
$this->_em->getConfiguration()->setAllowPartialObjects(false);
|
||||||
$metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceCustomer');
|
$metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceCustomer');
|
||||||
$metadata->getAssociationMapping('cart')->fetchMode = AssociationMapping::FETCH_LAZY;
|
$metadata->getAssociationMapping('mentor')->fetchMode = AssociationMapping::FETCH_EAGER;
|
||||||
|
|
||||||
$query = $this->_em->createQuery('select c from Doctrine\Tests\Models\ECommerce\ECommerceCustomer c');
|
$query = $this->_em->createQuery('select c from Doctrine\Tests\Models\ECommerce\ECommerceCustomer c');
|
||||||
$result = $query->getResultList();
|
$result = $query->getResultList();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user