[DDC-1496] OrphanRemove does not work when using clear() without initializing the collection before Created: 16/Nov/11  Updated: 18/Nov/11  Resolved: 18/Nov/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Georg Wächter Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Collection items (marked with orphanRemoval=true) are not removed from the database correctly if
1. the collection is not initialized
2. we now call ->clear() on it.

I think the problem is that PersistentCollection::clear() iterates through the uninitialized collection which is empty in this case. Thus the scheduleOrphanRemoval() method is never called.

The best example is within the doctrine 2 documentation: http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#orphan-removal . Calling $this->addresses->clear() raises this bug.

I'm currently helping myself by fixing the situation with accessing the elements of the collection before calling ->clear().



 Comments   
Comment by Benjamin Eberlei [ 18/Nov/11 ]

fixed and merged into 2.1.x





[DDC-1477] GH-177: ProxyFactory was redeclaring methods in some OSs Created: 08/Nov/11  Updated: 25/Jul/12  Resolved: 13/Nov/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Pull-Request was automatically synchronized:
https://github.com/doctrine/doctrine2/pull/177

The ProxyFactory was redeclaring methods serialize and unserialize (in my case) on the cache file on some OSs.

Here is the full comment with some screenshots: https://github.com/symfony/symfony/issues/2501



 Comments   
Comment by Benjamin Eberlei [ 13/Nov/11 ]

Fixed

Comment by Benjamin Eberlei [ 25/Jul/12 ]

A related Github Pull-Request [GH-177] was opened
https://github.com/doctrine/dbal/pull/177

Comment by Benjamin Eberlei [ 25/Jul/12 ]

A related Github Pull-Request [GH-177] was closed
https://github.com/doctrine/dbal/pull/177





[DDC-1474] Selecting expressions involving the unary minus operator will not work, whereas the EBNF syntax definitions for DQL say they should Created: 06/Nov/11  Updated: 15/Nov/11  Resolved: 15/Nov/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Minor
Reporter: Daniel Alvarez Arribas Assignee: Fabio B. Silva
Resolution: Fixed Votes: 0
Labels: None


 Description   

DQL queries like:

SELECT - someEntity.someNumericField FROM \SomeEntity someEntity

will result in a syntax error:

[Syntax Error] line 0, col 7: Error: Expected IdentificationVariable | StateFieldPathExpression | AggregateExpression | "(" Subselect ")" | ScalarExpression, got '-''

I think this should work, because the relevant EBNF definitions state the following:

SimpleSelectExpression  ::= ScalarExpression | IdentificationVariable |
                            (AggregateExpression [["AS"] AliasResultVariable])
ScalarExpression       ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression
                           BooleanPrimary | EntityTypeExpression | CaseExpression
SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
ArithmeticTerm             ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}*
ArithmeticFactor           ::= [("+" | "-")] ArithmeticPrimary
ArithmeticPrimary          ::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")"
                               | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings
                               | FunctionsReturningDatetime | IdentificationVariable | InputParameter | CaseExpression
SingleValuedPathExpression                ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
StateFieldPathExpression                  ::= IdentificationVariable "." StateField | SingleValuedAssociationPathExpression "." StateField

Therefore, the expression "- someEntity.someField" is a legitimate arithmetic factor, which ultimately should be a legitimate scalar expression too, which is a legitimate simple select expression.

Fortunately, this is easy to work around, by simply subtracting from zero, like in:

SELECT 0 - someEntity.someNumericField FROM \SomeEntity someEntity


 Comments   
Comment by Benjamin Eberlei [ 15/Nov/11 ]

Fixed.





[DDC-1462] Extra Lazy and slice() on dirty collection Created: 31/Oct/11  Updated: 31/Oct/11  Resolved: 31/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

If i slice and the collection is dirty then i have to go to the database.



 Comments   
Comment by Benjamin Eberlei [ 31/Oct/11 ]

Fixed.





[DDC-1454] SQL error when requesting state for unknown joined inheritance entity with natural identifier Created: 25/Oct/11  Updated: 27/Oct/11  Resolved: 27/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Aigars Gedroics Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu 11.10, PHP 5.3.6, MySQL 5.1.58


Attachments: File DDC1454Test.php    

 Description   

When having unknown (not cached by UnitOfWork) joined inheritance entity with natural identifier (GENERATOR_TYPE_NONE), method UnitOfWork::getEntityState() fails with SQL error:

Column not found: 1054 Unknown column 't1.file_id' in 'where clause'

Will attach testcase right after creating the issue.



 Comments   
Comment by Aigars Gedroics [ 25/Oct/11 ]

Test case.

Comment by Aigars Gedroics [ 26/Oct/11 ]

Possible change diff for file Doctrine/ORM/Persisters/BasicEntityPersister.php from Doctrine ORM 2.1.2.

Idea is to use the main table (not inherited one) if the column is a part of ID. So, I guess, it will be in both tables.

@@ -1197,7 +1197,7 @@ class BasicEntityPersister
             $conditionSql .= $conditionSql ? ' AND ' : '';
 
             if (isset($this->_class->columnNames[$field])) {
-                if (isset($this->_class->fieldMappings[$field]['inherited'])) {
+                if (isset($this->_class->fieldMappings[$field]['inherited']) && empty($this->_class->fieldMappings[$field]['id'])) {
                     $conditionSql .= $this->_getSQLTableAlias($this->_class->fieldMappings[$field]['inherited']) . '.';
                 } else {
                     $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.';
Comment by Benjamin Eberlei [ 27/Oct/11 ]

Fixed





[DDC-1436] Problems with identity map on self-referencing Created: 18/Oct/11  Updated: 18/Nov/11  Resolved: 18/Nov/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.1
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Critical
Reporter: Konstantin Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Symfony2



 Description   
/**
 * @Orm\Entity
 * @Orm\Table(name="tt_content")
 */
class Page
{
	/**
	 * @Orm\Id
	 * @Orm\GeneratedValue
	 * @Orm\Column(type="integer", name="id")
	 */
	protected $id;

	/**
	 * @Orm\ManyToOne(targetEntity="Page", inversedBy="children")
	 * @Orm\JoinColumn(name="pid", referencedColumnName="id")
	 */
	protected $parent;

	/** @Orm\OneToMany(targetEntity="Page", mappedBy="parent") */
	protected $children;

	/** @Orm\Column(name="page_title") */
	protected $title;
}

$id = 5;

// step 1 
$page = $this
	->getEntityManager('read')
	->createQuery('
		SELECT p, parent
		FROM OloloContentBundle:Page p
			LEFT JOIN p.parent parent
		WHERE p.id = :id
	')
	->setParameter('id', $id)
	->getOneOrNullResult();

// step 2
$page = $this->getEntityManager('read')->find('OloloContentBundle:Page', $id);
var_dump($page->getParent()->getParent()); // expected instance of Page, but got null

When I added one more fetch join for parent then I got Page.



 Comments   
Comment by Benjamin Eberlei [ 14/Nov/11 ]

Can you test against master again? I made a fix in context of DDC-1452 that i think could solve this issue.

Comment by Konstantin [ 15/Nov/11 ]

I will do it

Comment by Konstantin [ 15/Nov/11 ]

I cann't run master branch on current env (Symfony 2.0.2).

MappingException: The association mapping 'eventArea' misses the 'targetEntity' attribute, but targetEntity present. Can you merge fix into 2.1.x branch?

Comment by Benjamin Eberlei [ 18/Nov/11 ]

I am not sure this fix is mergable in 2.1, also it is a rather complex change that i don't want to merge back to the stable branch for stability reasons.

Let me try to reproduce this in a test and then go further from there.

Comment by Benjamin Eberlei [ 18/Nov/11 ]

DDC-1452 is indeed the same bug as this one and the fix works.

Comment by Benjamin Eberlei [ 18/Nov/11 ]

I cant merge this as with the latest refactorings it gives hundrets of conflicts, but will re-apply manually.

Comment by Benjamin Eberlei [ 18/Nov/11 ]

Backported and fixed in 2.1.x

Comment by Konstantin [ 18/Nov/11 ]

Thank you very much, Benjamin!





[DDC-1435] Exception thrown when generating SQL from a DQL subselect where the entity has a foreign key as a primary key Created: 18/Oct/11  Updated: 07/Jun/12  Resolved: 29/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Payam Hekmat Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None


 Description   

If an entity has a foreign key as part of its primary key and you try to query that entity in a subselect clause in DQL, an exception is thrown in ClassMetadataInfo->getQuotedColumnName. The problem seems to be that it's only considering the field mappings rather than both the field and association mappings when it's looking for the correct column name.

Example entities:

  • Article(id primary key, title, content)
  • ArticleTag(article_id, tag, primary key (article_id, tag))

Example DQL: select art from Article art where exists (select tag from ArticleTag tag where tag.article = art)



 Comments   
Comment by Benjamin Eberlei [ 28/Oct/11 ]

Verified:

    /**
     * @group DDC-1435
     */
    public function testForeignKeyAsPrimaryKeySubselect()
    {
        $this->assertSqlGeneration(
            "SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)",
            ""
        );
    }

This however is not possible anyways, since you cannot have "r" in a SimpleSelectExpression when it resolves to multiple columns. You can try to select just one arbitrary field, for example."SELECT r.foobar FROM .."

Comment by Payam Hekmat [ 28/Oct/11 ]

Would that just be a documentation issue then? I didn't see that restriction in the grammar, but I may have overlooked it. I issued a pull request for this issue assuming that an association mapped field is valid input for getQuotedColumnName.

Selecting a single field does work fine.

Comment by Benjamin Eberlei [ 28/Oct/11 ]

Did you touch this in your latest changes to SimpleSelectExpression guilherme?

Comment by Guilherme Blanco [ 29/Oct/11 ]

Hi,

@beberlei No. Issue was totally unrelated.
Please merge my commit to 2.1.X.

The issue was caused by the identifier iteration was considering that @Id fields are always fields, never associations. You may see that in method getQuoteColumnName.

Solution was to create a new method called getQuotedIdenitiferColumnNames and consume it in SqlWalker.
This addresses the issue.

Committed patch and test case as of: https://github.com/doctrine/doctrine2/commit/0ec2cc557f51d6240396689e36101f62d84d2a38

Cheers,

Comment by Benjamin Eberlei [ 29/Oct/11 ]

Merged into 2.1.x

Comment by Benjamin Eberlei [ 08/Nov/11 ]

This issue is referenced in Github Pull-Request GH-159
https://github.com/doctrine/doctrine2/pull/159

Comment by Benjamin Eberlei [ 07/Jun/12 ]

A related Github Pull-Request [GH-159] was opened
https://github.com/doctrine/dbal/pull/159





[DDC-1421] SQL Casing in BasicEntityPersister::_getSelectColumnAssociationSQL Created: 15/Oct/11  Updated: 15/Oct/11  Resolved: 15/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

SQL Casing is not applied to column alias and method is used twice unnecessarily.






[DDC-1420] doctrine orm:validate-schema failure when using Migrations Created: 14/Oct/11  Updated: 31/Oct/11  Resolved: 31/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Minor
Reporter: Denis Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None
Environment:

Linux, php 5.3.8



 Description   

I'm using Doctrine 2.1.2 with Migrations 2.0. Doctrine cli tool works
correctly for both schema creation (from annotations) and migrations
but, after using the tool to validate the schema i get the following
error:

[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current
mapping file.

The failure is caused by the doctrine_migration_versions table that
the migration project has created in the db of my project.

orm:validate-schema fails because the relation is not defined as an
entity in the annotations.



 Comments   
Comment by Benjamin Eberlei [ 31/Oct/11 ]

Fixed





[DDC-1414] UnitOfWork#getCommitOrder() does not add dependencies for all related classes Created: 11/Oct/11  Updated: 15/Oct/11  Resolved: 15/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2, Git Master
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Critical
Reporter: Petri Mahanen Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

All



 Description   

getCommitOrder() does not add dependencies for all related classes. This causes database-level exceptions in certain cases, as insertion order can be calculated incorrectly, and foreign key constraints fail.

An example case in pseudocode:

A: ManyToOne to B, nullable=true
B: ManyToOne to C, nullable=false
C: no owning relations

a = new A()
em->persist(a)
em->flush()     // does CommitOrderCalculator->addClass(B), but does not add B's dependency to C

c = new C()
b = new B(c)

em->persist(c)
em->persist(b)
em->flush()     // CommitOrderCalculator->hasClass(B) == true, dependencies not added, foreign key constraint fails

Suggested fix against master:

diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index ea516f3..991acac 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -853,6 +853,7 @@ class UnitOfWork implements PropertyChangedListener
                     $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
                     if ( ! $calc->hasClass($targetClass->name)) {
                         $calc->addClass($targetClass);
+                        $newNodes[] = $targetClass;
                     }
                     $calc->addDependency($targetClass, $class);
                     // If the target class has mapped subclasses,

This $newNodes[] push is done for all new classes in $entityChangeSet (above) and $targetClass->subClasses (below), but not for $targetClass itself. I'm assuming this is a bug, not by design.



 Comments   
Comment by Benjamin Eberlei [ 15/Oct/11 ]

Fixed.





[DDC-1411] onCascade property gets wrong value when entities are generated Created: 10/Oct/11  Updated: 15/Oct/11  Resolved: 15/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.1
Fix Version/s: 2.1.3, 2.2
Security Level: All

Type: Bug Priority: Major
Reporter: Vinícius Borriello Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Unix/Apache/PHP 5.3/MySQL



 Description   

I'm using this cmd to generate entities "/path/to/php path/to/doctrine orm:generate-entities --generate-annotations="1" ~/some/path".

The CASCADE option for ONDELETE columns is being wrongly generated, the right would be: onDelete="CASCADE" but it is being generated as onDelete=true



 Comments   
Comment by Benjamin Eberlei [ 15/Oct/11 ]

Fixed





[DDC-1410] leftJoin with condition WITH & Object Hydratation problem. Created: 10/Oct/11  Updated: 07/Jun/12  Resolved: 28/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: Git Master
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Blocker
Reporter: Thomas Tourlourat - Armetiz Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 2
Labels: None
Environment:

Debian 5 dotdeb
PHP 5.3
MySQL 5.0
Apache 2.2


Attachments: Text File ObjectHydrator_DDC-1410_v1.patch    

 Description   

Here an example of a simple QueryBuilder :

$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select ( "player, options" );
$queryBuilder->from ( "Player_Model_Entity_Player", "player");
$queryBuilder->where ("player.idPlayer = 12");
$queryBuilder->leftJoin ("player.options", "options", "WITH", "options.enabled = :enabled");
$queryBuilder->setParameter ("enabled", 1);

OptionA & OptionB & OptionC three entities.
User case :

  • OptionA.enabled = 1 & OptionB.enabled = 1 & OptionC.enabled = 1 : OK - All options are return.
  • OptionA.enabled = 1 & OptionB.enabled = 0 & OptionC.enabled = 0 : OK - only optionA is return.
  • OptionA.enabled = 1 & OptionB.enabled = 0 & OptionC.enabled = 1 : OK - only optionA & optionC is return.
  • OptionA.enabled = 0 & OptionB.enabled = 1 & OptionC.enabled = 1 : KO - no option return.
  • OptionA.enabled = 0 & OptionB.enabled = 0 & OptionC.enabled = 0 : OK - no option return.

I have test on OneToMany configuration and I have not problem. The problem only appear with ManyToMany relationships.

The problem seems to be on hydratation. The data return on SQL command seems to be correct.



 Comments   
Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I have made some other search about it.

On the queryBuilder described above, I was using getSingleResult / getResult.
When I'm using getScalarResult I can see data of every options.

Here the scalar result :

array(3) {
  [0]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    NULL
    ["options_enabled"]=>
    NULL
  }
  [1]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    int(2)
    ["options_enabled"]=>
    bool(true)
  }
  [2]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    int(4)
    ["options_enabled"]=>
    bool(true)
  }
}

Do you have any clue ?

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I think I have find the problem.

See patch.
I have test the modification, it seem to be okay.

In the 2.1.2 version, If the first related object wasn't a "nonemptyComponents", the ObjectHydrator initialized the collection by a specific way.

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

It's a patch for Doctrine/ORM/Internal/Hydration/ObjectHydrator.php version 2.1.2.

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I have add a correction on Github : https://github.com/armetiz/doctrine2/commit/42d507632fd27a23220c38bb867b611c3caaab8e

Comment by Benjamin Eberlei [ 25/Oct/11 ]

Thanks for digging into that, I will evaluate this issue

Comment by Thomas Tourlourat - Armetiz [ 25/Oct/11 ]

No problem, It was blocking for me.
But I don't understand why this bug doesn't appear to other users. Because of that, I'm wondering if it's a real bug or a miss configuration on my app.

To be sure, the best will be to create a new test, but I'm not really familiar to create ORM test case..

Thomas.

Comment by Benjamin Eberlei [ 25/Oct/11 ]

can you post your mappings?

Comment by Thomas Tourlourat - Armetiz [ 26/Oct/11 ]

PlayerEntity :

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
	<entity name="PlayerEntity">
		<many-to-many field="options" target-entity="OptionEntity" mapped-by="players" />
	</entity>
</doctrine-mapping>
{/code}

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd" >
<entity name="OptionEntity" table="options">
<many-to-many field="players" target-entity="PlayerEntity" inversed-by="options">
<cascade>
<cascade-merge />
</cascade>
<join-table name="compo_option_player" />
</many-to-many>
</entity>
</doctrine-mapping>

{/code}

I have post all the mapping, but it's Doctrine compliant.
PlayerEntity extends PlayerBaseEntity, and Option is a standalone Entity.
All define an auto generated identifier.
The join table is correctly configured.

Do you need this mapping to create tests ?
To sum-up, this is a simply ManyToMany relation between an inheritance Entity & a simple Entity.

Do you need any else ?

Thomas.

Comment by Benjamin Eberlei [ 28/Oct/11 ]

Fixed.

Comment by Benjamin Eberlei [ 08/Nov/11 ]

This issue is referenced in Github Pull-Request GH-161
https://github.com/doctrine/doctrine2/pull/161

Comment by Benjamin Eberlei [ 07/Jun/12 ]

A related Github Pull-Request [GH-161] was opened
https://github.com/doctrine/dbal/pull/161

Comment by Benjamin Eberlei [ 07/Jun/12 ]

A related Github Pull-Request [GH-161] was closed
https://github.com/doctrine/dbal/pull/161





[DDC-1402] Huge performance leak in SingleTablePersister Created: 04/Oct/11  Updated: 10/Oct/11  Resolved: 10/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1, 2.1.1, 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Critical
Reporter: Sylvain Bernier Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File doctrine-orm-2.1.0-SingleTablePersister.patch    

 Description   

This code :

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
 */
class Person
{
    /** @Id @Column(type="integer") */ private $id;
}

/**
 * @Entity
 */
class Employee extends Person
{
    /** @Column(type="integer") */ private $a;
    /** @Column(type="integer") */ private $b;
    /** @Column(type="integer") */ private $c;
    /** @Column(type="integer") */ private $d;
    /** @Column(type="integer") */ private $e;
    /** @Column(type="integer") */ private $f;
    /** @Column(type="integer") */ private $g;
    /** @Column(type="integer") */ private $h;
}

foreach (range(0, 20) as $i) {
    $time = microtime(true);
    foreach (range(1, 100) as $j) {
        $id = ($i * 100) + $j;
        $entityManager->find('Person', $id);
    }
    printf("%4d ==> %f\n", $id, microtime(true) - $time);
}

Will output:

 100 ==> 0.461275
 200 ==> 1.128404
 300 ==> 1.823122
 400 ==> 2.521054
 500 ==> 3.232034
 600 ==> 3.950081
 700 ==> 4.648849
 800 ==> 5.380236
 900 ==> 6.080108
1000 ==> 6.807214
1100 ==> 7.519942
1200 ==> 8.238971
1300 ==> 8.951686
1400 ==> 9.648996
1500 ==> 10.370053
1600 ==> 11.069523
1700 ==> 11.791530
1800 ==> 12.481427
1900 ==> 13.190570
2000 ==> 13.902810
2100 ==> 14.671100

With the first and last SELECT queries as:

SELECT t0.id AS id1, discr, t0.a AS a2, t0.b AS b3, t0.c AS c4, t0.d AS d5, t0.e AS e6, t0.f AS f7, t0.g AS g8, t0.h AS h9 FROM Person t0 WHERE t0.id = 1 AND t0.discr IN ('person', 'employee')

...

SELECT t0.id AS id1, discr, t0.a AS a16794, t0.b AS b16795, t0.c AS c16796, t0.d AS d16797, t0.e AS e16798, t0.f AS f16799, t0.g AS g16800, t0.h AS h16801 FROM Person t0 WHERE t0.id = 2100 AND t0.discr IN ('person', 'employee')

Notes:

  • Last 100 SELECT queries take more than 14 seconds to execute! (table is empty)
  • Filed as a bug because a real life scenario caused major performance leak and memory usage when attempting to do 6000 calls to find().

Analysis:

  1. Calls to SingleTablePersister::_getSelectColumnListSQL() do not use BasicEntityPersister::$_selectColumnListSql
  2. This generates a lot of calls to _getSelectColumnSQL() (See last SELECT query with alias counter up to 16800)
  3. This generates a lot of calls to addFieldResult()
  4. And this fills up pretty quickly ResultSetMapping::$declaringClasses
  5. To finally put a huge burden on SimpleObjectHydrator::_prepare() where it iterates on $this->_rsm->declaringClasses and calls getClassMetadata() for each one!
  6. And all that, including _prepare(), is executed for each SELECT, even though none of them find any result (the table is empty).

I fixed my project using the following patch:

diff --git a/doctrine-orm/Doctrine/ORM/Persisters/SingleTablePersister.php b/doctrine-orm/Doctrine/ORM/Persisters/SingleTablePersister.php
index f910a8e..78b27cb 100644
--- a/doctrine-orm/Doctrine/ORM/Persisters/SingleTablePersister.php
+++ b/doctrine-orm/Doctrine/ORM/Persisters/SingleTablePersister.php
@@ -41,6 +41,15 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
     /** {@inheritdoc} */
     protected function _getSelectColumnListSQL()
     {
+        /** @see BasicEntityPersister::_getSelectColumnListSQL() */
+        if ($this->_selectColumnListSql !== null) {
+            return $this->_selectColumnListSql;
+        }
+
+        #####
+        #####
+        #####
+
         $columnList = parent::_getSelectColumnListSQL();
 
         // Append discriminator column
@@ -74,7 +83,13 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
             }
         }
 
-        return $columnList;
+        #####
+        #####
+        #####
+
+        /** @see BasicEntityPersister::_getSelectColumnListSQL() */
+        $this->_selectColumnListSql = $columnList;
+        return $this->_selectColumnListSql;
     }
 
     /** {@inheritdoc} */

I do not know if this patch is safe for everybody.

But, well, you can easily reproduce the problem and analyze the phenomenon using a profiler on the sample code provided.

Thanks for this great piece of software. I hope this will help you find and fix the bug.



 Comments   
Comment by Benjamin Eberlei [ 10/Oct/11 ]

good catch, thank you very much!

fixed and merged back into 2.1.x





[DDC-1400] joining and selecting associated collection, which is using indexBy, to a query is triggering UPDATE queries for each collection element which were joined. Created: 30/Sep/11  Updated: 02/Jan/12  Resolved: 02/Jan/12

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Reio Piller Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: File DDC1400Test.php    

 Description   
 
/**
 * @Entity
 */
class Article
{

    /**
     * @Id
     * @Column(type="integer")
     */
    protected $id;

    /**
     * @OneToMany(targetEntity="UserState", mappedBy="article", indexBy="userId", fetch="EXTRA_LAZY")
     */
    protected $userStates;

    .......

}

/**
 * @Entity
 */
class User
{

    /**
     * @Id
     * @Column(type="integer")
     */
    protected $id;

    /**
     * @OneToMany(targetEntity="UserState", mappedBy="user", indexBy="articleId", fetch="EXTRA_LAZY")
     */
    protected $userStates;

    .......

}

/**
 * @Entity
 */
class UserState
{

    /**
      * @Id
     *  @ManyToOne(targetEntity="Article", inversedBy="userStates")
     */
    protected $article;

    /**
      * @Id
     *  @ManyToOne(targetEntity="User", inversedBy="userStates")
     */
    protected $user;

    /**
     * @Column(name="user_id", type="integer")
     */
    protected $userId;

    /**
     * @Column(name="article_id", type="integer")
     */
    protected $articleId;

    /**
     * @Column(type="boolean")
     */
    protected $hasLiked;

    .......

}

$q = $em->createQuery("SELECT a, s FROM Article a JOIN a.userStates s WITH s.user = :activeUser");
$q->setParameter('activeUser', $activeUserId);
$q->getResult();

if i $em->flush() now it will execute lots of update queries like:
UPDATE userstate SET article_id = ? WHERE user_id = ? AND article_id = ?



 Comments   
Comment by Benjamin Eberlei [ 15/Oct/11 ]

I think your mapping is wrong. You cannot map an @Id + @ManyToOne and then remap the same column using @Column.

What exactly are the parameters to the query? How is it updating article_id ?

Is this even affected by "indexBy"? Can you remove them and try again?

Comment by Reio Piller [ 17/Oct/11 ]

I have to use @Id + $ManyToOne and @Column on the same database field because indexBy only supports normal @Columns as key. We have used this workaround numerous times in our system without any issues.

And it seems that this is not causing the updates. Here is another example:

 
/**
 * @Entity
 */
class Article
{

    /**
     * @Id
     * @Column(type="integer")
     */
    protected $id;

    /**
     * @OneToMany(targetEntity="ArticleText", mappedBy="article", indexBy="locale", fetch="EXTRA_LAZY")
     */
    protected $texts;

    .......

}

/**
 * @Entity
 */
class ArticleText
{

    /**
     * @Id
     * @ManyToOne(targetEntity="Article", inversedBy="texts")
     */
    protected $article;

    /**
     * @Id
     * @Column
     */
    protected $locale;

   /**
    * @Column
    */
   protected $title;

    .......

}

$q = $em->createQuery("SELECT a, t FROM Article a JOIN a.texts t WITH t.locale = :activeLocale");
$q->setParameter('activeLocale', 'en');

$em->flush(); // dummy flush, no queries made

$q->getResult();

$em->flush(); // this will trigger the updates

UPDATE article_text SET article_id = 1 WHERE locale = 'en' AND article_id = 1
UPDATE article_text SET article_id = 2 WHERE locale = 'en' AND article_id = 2
UPDATE article_text SET article_id = 3 WHERE locale = 'en' AND article_id = 3
UPDATE article_text SET article_id = 4 WHERE locale = 'en' AND article_id = 4
UPDATE article_text SET article_id = 5 WHERE locale = 'en' AND article_id = 5
.......

it does it one per article for all articles in result.

If i remove the indexBy annotation the updates disappear. Extra lazy loading has no effect on this bug.

Comment by Benjamin Eberlei [ 19/Nov/11 ]

Attached is a working testcase with your example code.

Can you please verify that it follows your example exactly and try to make it generate those UPDATEs?

Comment by Benjamin Eberlei [ 02/Jan/12 ]

This is fixed in 2.1.3, it was a bug until 2.1.2





[DDC-1399] Wrong count() value in many-to-many relationship and EXTRA_LAZY Created: 30/Sep/11  Updated: 31/Oct/11  Resolved: 31/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Paweł Gniadkowski Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Symfony 2.0.3 / LAMP



 Description   

Relation many-to-many, EXTRA_LAZY, $user is owning side. Without EXTRA_LAZY all is ok.

Main problem: counter is increased twice.

$user->getPhotos()->count(); // returns 100 (OK)
$user->addPhoto($photo);
$user->getPhotos()->count(); // returns 101 (OK)
$em->flush();
$user->getPhotos()->count(); // returns 102 (WRONG! Should be 101)



 Comments   
Comment by Benjamin Eberlei [ 31/Oct/11 ]

verified.

Comment by Benjamin Eberlei [ 31/Oct/11 ]

fixed





[DDC-1386] getPartialReference() will result in data loss if default values are used Created: 21/Sep/11  Updated: 15/Oct/11  Resolved: 15/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Stefan Klug Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Dependency
depends on DDC-209 Add the notion of read-only entities Resolved

 Description   

If a entity uses default values e.g.

class User {
    private $id;
    private $name = "unnamed";
}

a reference returned from EntityManager::getPartialReference() will automatically result in a scheduled update for this entity (and all fields with default values), because the EM expects the fields of the entity to be empty. This results in resetting all data inside the database to the default values when doing an $em->flush().

Regards Stefan



 Comments   
Comment by Benjamin Eberlei [ 15/Oct/11 ]

Verified, have a fix for this already but its rather tricky with how far i want to push this.

Comment by Benjamin Eberlei [ 15/Oct/11 ]

I committed a fix into master and 2.1.x https://github.com/doctrine/doctrine2/commit/3801e0c230b5bf4060ee72800a270340ffee2355

This could somewhat be considered a BC. But i doubt people use partial objects to update the fields they omitted.





[DDC-1383] Inheritance superclass object is created after merging entity referencing to discriminated entity Created: 19/Sep/11  Updated: 15/Oct/11  Resolved: 15/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.1
Fix Version/s: 2.1.3, 2.2
Security Level: All

Type: Bug Priority: Major
Reporter: Aigars Gedroics Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu 11.04, MySQL 5.1.54-1ubuntu4, PHP 5.3.5-1ubuntu7.2


Attachments: File DDC1383Test.php    

 Description   

Problem is that after merging the object with a reference to some other entity with inheritance (is one of the superclass's discriminator map), the referenced object has wrong instance (it is Proxy object). It is instance of the superclass not the extended class.

In my test case I have joined inheritance model with only two entities to make things simple as possible.

First is the base entity (I have even marked it as abstract):

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="integer")
 * @DiscriminatorMap({1 = "Entity"})
 */
abstract class AbstractEntity

and one entity which extends from the first one:

/**
 * @Entity
 */
class Entity extends AbstractEntity {
	/**
	 * @ManyToOne(targetEntity="AbstractEntity")
	 * @var AbstractEntity
	 */
	protected $reference;

In this scheme I've got 2 objects, first referencing to the second. They both are inserted in the database with no problems.

$child = new Entity();
$parent = new Entity();
$child->setReference($parent);

After the flush I try merging the child entity into the entity manager, the parent entity reference is not instance of Entity\Entity anymore.

You can see full test case in the archive attached.



 Comments   
Comment by Aigars Gedroics [ 26/Sep/11 ]

Attached standardized test case.

Comment by Benjamin Eberlei [ 15/Oct/11 ]

Fixed.





[DDC-1382] getIdentifierValues causes an exception on entyties that have only association keys Created: 19/Sep/11  Updated: 15/Oct/11  Resolved: 03/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Asmir Mustafic Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None
Environment:

ubuntu



 Description   

On entities that have only association keys as primary keys:

Calling BasicEntityPersister::exists() cause the invocation of ClassMetadata::getIdentifierValues() method.
This method returns associated entities as identifier values.
Then BasicEntityPersister::exists() tries to converts these objects to string, instead of searching their primary keys.

Some problems:

  • getIdentifierValues have not access to external world (only its class metadata and the current entity).
  • getIdentifierValues is uses in many places of doctrine

(sorry for my bad English)



 Comments   
Comment by Guilherme Blanco [ 03/Oct/11 ]

Fixed in https://github.com/doctrine/doctrine2/commit/24042863acbabdcd0fa1432135a9836467f3bce7

It should be available in next release.





[DDC-1358] Native Query hydration ignores empty entity doublons Created: 02/Sep/11  Updated: 16/Oct/11  Resolved: 16/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.1.3, 2.2
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Lorteau Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Debian 6, Symfony 2, Doctrine 2



 Description   

My case is the follwing :

In a range of dates, I want to know if an entity has been defined for each day. So the raw SQL result would looks like :

DATE              ID NAME
--------- ---------- -------------
19-SEP-11          4 [Entity Name]
20-SEP-11          1 [Entity Name]
21-SEP-11          2 [Entity Name]
22-SEP-11          3 [Entity Name]
23-SEP-11       NULL NULL
24-SEP-11       NULL NULL
25-SEP-11       NULL NULL
26-SEP-11       NULL NULL
27-SEP-11          7 [Entity Name]
28-SEP-11          6 [Entity Name]
29-SEP-11          5 [Entity Name]

11 rows selected.

The range calculation forced me to use Native Query, but I stumbled upon a strange behavior : the Result array showed less records than the raw SQL would provide. After some dirty debugging, I found out that during hydration, an array of previously hydrated object keys was stored ObjectHydrator->_identifierMap. The key of null elements (the gap in the SQL result above) is stored too. The problem is that when there is multiple empty elements, hydration only keeps one, and forget the others, thus reducing the overall size of the output result.

I've already come up with a quick n'dirty fix wich suits my current needs, but it would be better if this issue was addressed at a more global level.

Here's the one-liner fix :

Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 397 was :
                if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]]) ) {
Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 397 now :
                if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]]) || str_replace( '|', '', $id[$dqlAlias]) == '') {


 Comments   
Comment by Benjamin Eberlei [ 04/Sep/11 ]

Doesnt he still hydrate an empty object for this row then? Why are you even using the object hydrator? I rather tend to go and throw an exception if for a query using the ObjectHydrator $id[$dqlAlias] is empty, because frankly this is just not supported.

Comment by Benjamin Lorteau [ 04/Sep/11 ]

He does hydrate one empty object for the first line with empty ID, but he does not hydrate further empty object.

Thus, instead of having an array with the following objects :

 
Entity(id=4)
Entity(id=1)
Entity(id=2)
Entity(id=3)
Entity(id=)
Entity(id=)
Entity(id=)
Entity(id=)
Entity(id=7)
Entity(id=6)
Entity(id=5)

I got :

 
Entity(id=4)
Entity(id=1)
Entity(id=2)
Entity(id=3)
Entity(id=)
Entity(id=7)
Entity(id=6)
Entity(id=5)
Comment by Benjamin Eberlei [ 04/Sep/11 ]

Yes, but can you show me your DQL statement?

Comment by Benjamin Lorteau [ 05/Sep/11 ]

I'm using Native Query, so I guess it's not DQL, but here's the query (Oracle SQL)

SELECT *
FROM (
    SELECT to_date(:date_start,\'dd-mm-yyyy\') + rownum -1 as period_date
    FROM all_objects
    WHERE rownum <= to_date(:date_end,\'dd-mm-yyyy\') - to_date(:date_start,\'dd-mm-yyyy\')+1
)
LEFT JOIN entity ON period_date = entity_date',
Comment by Benjamin Eberlei [ 15/Oct/11 ]

For the Array- and ObjectHydrator the ID is a required result.

I am not sure how to proceed with this, i think the right behavior is to return null as the object when no id is found. What do you think?

Is the Date a scalar value of the result?

Comment by Benjamin Lorteau [ 15/Oct/11 ]

The expected results would be, in order of preference :

  • Entity without id set (like in my example above)
  • null value

And yes, the Date was an additional scalar value for which I needed the Native Query

Comment by Benjamin Eberlei [ 16/Oct/11 ]

Your example lacks details but, for case one. Did the queries return values for the non-id columns of this entity?

Comment by Benjamin Lorteau [ 16/Oct/11 ]

Sorry for the concision, I didn't wanted to flood my comment with unrelated data.

The fact is the queries returned values for the non-id columns when the ID was set, and null values when not. I will update my comment.

Comment by Benjamin Eberlei [ 16/Oct/11 ]

I will go with adding NULL values there. This is more consistent, since null represents a non-existent entity.

Fixed and merged back into 2.1.x





[DDC-1346] Error when referencing aliased sub-select in where clause Created: 24/Aug/11  Updated: 31/Oct/11  Resolved: 05/Sep/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Critical
Reporter: Glen Ainscow Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None


 Description   

Example:

$qb->addSelect('(SELECT COUNT(tp2) FROM TeamPlayer tp2 WHERE tp2.team = t) AS test');

$qb->andWhere('test > 3');

[Semantical Error] line 0, col 186 near 'test > 3 ORDER': Error: 'test' does not point to a Class.



 Comments   
Comment by Benjamin Eberlei [ 27/Aug/11 ]

Assigned to Guilherme

Comment by Guilherme Blanco [ 05/Sep/11 ]

Fixed since commit https://github.com/doctrine/doctrine2/commit/6bbf2d9da35aa8ce500f26d671a135a00870e33a

Comment by Benjamin Eberlei [ 25/Sep/11 ]

Merged into 2.1

Comment by Benjamin Eberlei [ 31/Oct/11 ]

Merged into 2.1.x





[DDC-1335] QueryBuilder->form() does not allow the INDEX BY clause Created: 17/Aug/11  Updated: 25/Sep/11  Resolved: 25/Sep/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.1
Fix Version/s: 2.1.3
Security Level: All

Type: Improvement Priority: Minor
Reporter: Albert Casademont Assignee: Guilherme Blanco
Resolution: Fixed Votes: 3
Labels: None


 Description   

The QueryBuilder does not allow the INDEX BY clause in the form() function, so queris like 'SELECT u FROM User u INDEX BY u.id' are not possible just using the QueryBuilder. There is the option in the join() functions but when a join is not needed, you can only use DQL.

If you find id appropiate i'll work on a patch for the issue.



 Comments   
Comment by Sander Marechal [ 22/Aug/11 ]

I too would like to see this. I thought this issue was fixed with DDC-1145 but that only solves it for joins. It does not allow indexing on the result itself. I would like to see something like this:

$builder->select('u')->from('User')->indexBy('u.id');
$builder->getQuery()->getResult();

Or it may be better to implement it on the query (since it affects hydration rather than the query itself):

$builder->select('u')->from('User');
$builder->getQuery()->setIndex('u.id')->getResult();
Comment by Guilherme Blanco [ 25/Sep/11 ]

Fixed in https://github.com/doctrine/doctrine2/commit/80284a273ded303c059b013808d1199d8546d359





[DDC-1316] Insert statement for joined subclass presister doesn't type change the id values for subtables Created: 03/Aug/11  Updated: 31/Oct/11  Resolved: 05/Sep/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.1.3
Security Level: All

Type: Improvement Priority: Minor
Reporter: victor Velkov Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Dependency
is required for DDC-1320 Ship Immutable date time with Doctrin... Open

 Description   

Hi there,

I am using "Class Table Inheritance" and this are my entities.

**
 * @Entity
 * @Table (name="Vehicles")
 * @InheritanceType ("JOINED")
 * @DiscriminatorColumn (name="vehicleClass", type="string")
 * @DiscriminatorMap ({"own"="OwnCar", "renta"="RentedCar"})
 */
class Vehicle
{

	/**
	 * @Id
	 * @Column (name="vehicleID", type="integer")
	 */
	protected $vehicleID;

        /**
	 * @Id
         * @Column (name="dateFrom", type="datetime")
         */
	protected $dateFrom;

       .........
}
/**
 * @Table (name="OwnCars")
 * @Entity (repositoryClass="OwnCarRepo")
 */
class OwnCars_Model_Entity_OwnCar extends OwnCars_Model_Entity_Vehicle {

}

As you can see i am using composed id keys. The problem that i get is when building the insert statement the value for the second key which is type datetime is not transformed to date transformed but cast to integer and in the data base i got inserted value of 0000-00-00 00:00:00 instead of the date that i have given. After i did a bit of debugging i found the problem to be in the "Doctrine\ORM\Persisters\JoinedSubclassPersister" on line 163.

foreach ((array) $id as $idVal) {
    $stmt->bindValue($paramIndex++, $idVal);
}

As you can see when you are binding the values for the subtable ids you are not giving the type for the id. So for me to work i did a quick fix:

foreach ((array) $id as $columnNameIdentifier => $idVal) {

    /**
     * Fix untyped join inherited table.
     * All identifiers was typed now.
     */
    $type = \PDO::PARAM_STR;
    if (isset($this->_columnTypes[$columnNameIdentifier])) {
        $type = $this->_columnTypes[$columnNameIdentifier];
    }

    $stmt->bindValue($paramIndex++, $idVal, $type);
}

I hope that you will have time to take a look in to that problem soon as it is important for my project. Otherwise great work so far with the "ORM"

Have a nice day,
Victor



 Comments   
Comment by Benjamin Eberlei [ 06/Aug/11 ]

Even if we fixed that it wouldn't work to have a DateTime as primary key. Since PK values need to be "stringable".

Comment by Benjamin Eberlei [ 06/Aug/11 ]

Changed to improvement and link to DDC-1320

Comment by Guilherme Blanco [ 05/Sep/11 ]

Even though DateTime would be solved in a different way, I think the patch must be applied specially because the identifier can be anything else, including a user customized type.

I fixed this issue by commit: https://github.com/doctrine/doctrine2/commit/666691f84fd5a48d0eb6af7e93b83c2651555e61

Comment by Benjamin Eberlei [ 25/Sep/11 ]

Set to 2.2-DEV as one thing is unclear for me, see commit comment.

Comment by Benjamin Eberlei [ 31/Oct/11 ]

Merged into 2.1.x





[DDC-1266] doctrine drop sequence twice Created: 10/Jul/11  Updated: 31/Oct/11  Resolved: 31/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Mathieu Rochette Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File doctrine-orm_drop-sequence-twice.patch    
Issue Links:
Dependency
is required for DDC-1082 On PostgreSQL "doctrine orm:schema-to... Resolved

 Description   

when "_platform->supportsSequences()", a sequence can be droped twice

patch attached



 Comments   
Comment by Benjamin Eberlei [ 31/Oct/11 ]

Fixed in DBAL now by using SplObjectStorage to have only one unique sequence to drop (same for tables and foreign keys)





[DDC-1082] On PostgreSQL "doctrine orm:schema-tool:drop --force" will not delete all tables created by orm:schema-tool:create and still report success Created: 28/Mar/11  Updated: 31/Oct/11  Resolved: 31/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0.2
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Major
Reporter: Daniel Alvarez Arribas Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Dependency
depends on DDC-1266 doctrine drop sequence twice Resolved

 Description   

doctrine orm:schema-tool:drop --force

will report success even if there are still tables in the schema. The tables remaining are regular tables pertaining to the schema, which was originally created by the doctrine tools, and the tables should have be deleted regularly.

Repeating the command will delete all tables as expected.

I tried this with PostgreSQL 8.4.7 on Debian/Linux 5.0.

Btw, I think there should be another issue priority to assign to bugs like these. I made this a major bug, because in the existing priority system, according to the issue priority definitions, I think this closer to a major bug than to a minor bug because the system gives wrong information to the user, so that the underlying problem manifests in subsequent errors only, and is hard to detect if you believe the console tool's output. Still, it is easy to work around it. I would deem this a "normal" bug. "Major" seems to severe while "minor" seems not severe enough. Do you think it is worthwhile to introduce "normal"? This could help distinguish the real "major" bugs from those just declared as "major" because there was no option to declare them normal, and maybe give you a better focus on the more important bugs.



 Comments   
Comment by Daniel Alvarez Arribas [ 28/Mar/11 ]

In my database, out of 56 tables, 17 will not be deleted. I tried to find something these tables have in common, but could not find a pattern. After repeating the drop-schema command, three tables remain, including the top-most base table in the inheritance hierarchy, and a table referenced by it. Repeating the drop-schema command again drops those tables, too.

Comment by Benjamin Eberlei [ 01/May/11 ]

I changed alot in the dropSchema command, can you try again? The problem here is with all the foreign keys.

Comment by Daniel Alvarez Arribas [ 08/May/11 ]

Ok, thanks.

I tried again, now with Doctrine version 2.04.

I updated the Doctrine 2 installation to version 2.04, then recreated the complete database from scratch using doctrine orm:schema-tool:create --force.
Before recreating the database, I manually, dropped all tables in the database, and verified all tables were gone. I also regenerated the proxy classes, just in case it could have any effect.

The 86 tables have been created, as expected.

Then I tried to drop the database by calling doctrine orm:schema-tool:drop --force.

After using the command, there are still 17 tables remaining.

Overall, the result seems to be unaffected by the upgrade to the latest minor version.

Comment by Daniel Alvarez Arribas [ 08/May/11 ]

One thing that works now, though, is that calling doctrine orm:schema-tool:drop --force repeatedly, will also delete the 17 tables remaining after the first call.

So it did get better, although it does not work the first time it gets called, and still wrongly reports success the first time.

Comment by Benjamin Eberlei [ 19/Jun/11 ]

This should be fixed now, SchemaTool didnt handle sequence removal correctly before. Can you verify?

Comment by Daniel Alvarez Arribas [ 19/Jun/11 ]

Hey Ben,

I am currently travelling and do not have access to any development system. I will be back home by July, 1st and will have a look at this and let you know. Thanks for fixing it.

Comment by Mathieu Rochette [ 10/Jul/11 ]

maybe it's related to this bug : http://www.doctrine-project.org/jira/browse/DDC-1266

I just found this piece of code that mutes exceptions...

    public function dropSchema(array $classes)
    {
        $dropSchemaSql = $this->getDropSchemaSQL($classes);
        $conn = $this->_em->getConnection();

        foreach ($dropSchemaSql as $sql) {
            try {
                $conn->executeQuery($sql);
            } catch(\Exception $e) {
                
            }
        }
    }

maybe I'm missing something but even after reading the function comment this seems like a bad idea.
if dropTable is called within a transaction, the transaction will be aborted and the function will still return as if sucessful

Comment by Daniel Alvarez Arribas [ 20/Jul/11 ]

@Mathieu: Yes, that could very well be the root cause.

@Benjamin: I verified that the error is still there, now with Doctrine 2.1 and PostgreSQL 8.4. The command line tool (doctrine orm:schema-tool:drop --force) still wrongly reports success, in spite of several tables remaining in the schema.

Once I remove the try-catch-construct mentioned by Mathieu above (leaving the try block's content intact, of course), and reissue the command, there are exceptions. E.g.:

PDOException SQLSTATE[42P01]: Undefined table: 7 ERROR: sequence "some_random_sequence_seq" does not exist.

I believe that the intention of the try-catch-block above is to mute exactly that type of error, since it should not make any difference if something that is not there could not be deleted, because, after all, it is gone anyway. Unfortunately, it actually does make a difference in case several SQL-DDL commands are combined into a single call, because if any command in the call fails and raises an exception, all following commands in the same call will not be executed. I have not analyzed this further, but I think there is something smelly here.

Comment by Benjamin Eberlei [ 31/Oct/11 ]

Fixed





Generated at Thu Dec 18 20:54:38 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.