[DDC-2560] Schema tool invalid DDL syntax for default values Created: 19/Jul/13  Updated: 19/Jul/13

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

Type: Bug Priority: Major
Reporter: Ben Davies Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: schematool
Environment:

Postgresql



 Description   

Not sure if this is Postgresql specific or not, but here are the reproduction steps:

Have a table with a column setup like so:

ALTER TABLE usr ADD COLUMN contact_count integer;
ALTER TABLE usr ALTER COLUMN contact_count SET NOT NULL;
ALTER TABLE usr ALTER COLUMN contact_count SET DEFAULT 0;

Have a Entity Column Definition like so:

    /**
     * @var integer $contactCount
     *
     * @ORM\Column(name="contact_count", type="integer", nullable=false)
     */
    private $contactCount = 0;

orm:schema-tool:update will generate the following SQL:

ALTER TABLE usr ALTER contact_count SET ;

adding

options={"default":0}

to the column definition results in no sql being generated (correctly I assume)



 Comments   
Comment by Marco Pivetta [ 19/Jul/13 ]

The ORM doesn't support default column values.
That's fine-tuning you can do on the column definitions.

Your "workaround" is actually the correct way of dealing with this kind of DDL change.

Comment by Ben Davies [ 19/Jul/13 ]

I realise the ORM doesn't support default values, but the point is that the schematool picks up a diff in the columns, tries to generate a diff, and generates an invalid sql statement. Surely that is a bug?

Comment by Marco Pivetta [ 19/Jul/13 ]

Ben Davies the DBAL is responsible for generating this wrong DDL... Are you able to reproduce this in DBAL only?

Comment by Ben Davies [ 19/Jul/13 ]

Happy to try.

Comment by Ben Davies [ 19/Jul/13 ]

here you go
https://github.com/bendavies/dbal/blob/DBAL-561/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL561Test.php





[DDC-2524] Wrong commit order with cascade remove and double association Created: 24/Jun/13  Updated: 15/Jan/14

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

Type: Bug Priority: Major
Reporter: Matthieu Napoli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

We have stumbled upon a bug in a situation where a class A has the following associations to a class B:

  • A has one B (oneToOne unidirectional)
  • A has many B (oneToMany bidirectional)

Associations are with cascade remove.

We will submit a PR soon with a failing test case.

The failure is a MySQL foreign key violation exception when removing A (removals for B are executed after removals for A).



 Comments   
Comment by Valentin Claras [ 24/Jun/13 ]

Here a link to the pull request https://github.com/doctrine/doctrine2/pull/707

Comment by Matthieu Napoli [ 25/Jun/13 ]

The tests on Travis are failing as expected.

https://travis-ci.org/doctrine/doctrine2/builds/8382962

Here is the list of the queries executed for MySQL:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`doctrine_tests`.`CascadeRemoveOrderEntityG`, CONSTRAINT `FK_23681E8F99938CE5` FOREIGN KEY (`ownerO_id`) REFERENCES `CascadeRemoveOrderEntityO` (`id`))

With queries:

13. SQL: 'DELETE FROM CascadeRemoveOrderEntityO WHERE id = ?' Params: '1'
12. SQL: '"START TRANSACTION"' Params: 
11. SQL: 'SELECT t0.id AS id1, t0.ownerO_id AS ownerO_id2 FROM CascadeRemoveOrderEntityG t0 WHERE t0.ownerO_id = ?' Params: '1'
10. SQL: 'SELECT t0.id AS id1, t0.oneToOneG_id AS oneToOneG_id2 FROM CascadeRemoveOrderEntityO t0 WHERE t0.id = ?' Params: '1'
9. SQL: '"COMMIT"' Params: 
8. SQL: 'INSERT INTO CascadeRemoveOrderEntityG (ownerO_id) VALUES (?)' Params: '1'
7. SQL: 'INSERT INTO CascadeRemoveOrderEntityO (oneToOneG_id) VALUES (?)' Params: ''
6. SQL: '"START TRANSACTION"' Params: 

As you can see, the latest query causes a foreign key constraint violation (wrong order with the next, non-executed query).

Comment by Matthieu Napoli [ 25/Jun/13 ]

On the sqlite tests we can see better the order the queries are executed:

14. SQL: 'DELETE FROM CascadeRemoveOrderEntityG WHERE id = ?' Params: '1'
13. SQL: 'DELETE FROM CascadeRemoveOrderEntityO WHERE id = ?' Params: '1'
12. SQL: '"START TRANSACTION"' Params: 
11. SQL: 'SELECT t0.id AS id1, t0.ownerO_id AS ownerO_id2 FROM CascadeRemoveOrderEntityG t0 WHERE t0.ownerO_id = ?' Params: '1'
10. SQL: 'SELECT t0.id AS id1, t0.oneToOneG_id AS oneToOneG_id2 FROM CascadeRemoveOrderEntityO t0 WHERE t0.id = ?' Params: '1'
9. SQL: '"COMMIT"' Params: 
8. SQL: 'INSERT INTO CascadeRemoveOrderEntityG (ownerO_id) VALUES (?)' Params: '1'
7. SQL: 'INSERT INTO CascadeRemoveOrderEntityO (oneToOneG_id) VALUES (?)' Params: ''
6. SQL: '"START TRANSACTION"' Params: 

13 and 14 are in the wrong order.

Comment by Guilherme Blanco [ 03/Aug/13 ]

This situation is not supported and cannot be resolved within current Doctrine code.
You created a circular dependency between the entities A and B. It happened because A contains one B (oneToOne) and because B contains a pointer to A as part of oneToMany association.
That way, you'll always have a foreign key constraint issue from RDBMS, no matter which entity you try to remove first.

Because of that, I'mm marking this ticket as "can't fix".

Comment by Matthieu Napoli [ 05/Aug/13 ]

Guilherme Blanco I see what you mean, but the case we submitted is with a nullable foreign key. So the operation is permitted by the RDBMS.

A has one B (nullable oneToOne), and B has a pointer to A (manyToOne, not nullable).

As I said for the query log, B should be removed first, which is not the case (see above, line 13 and 14 should be inversed).

So this is fixable on the Doctrine side if I'm not mistaken.

Comment by Benjamin Eberlei [ 03/Jan/14 ]

Matthieu Napoli is this fixed with your DDC-2775 PR?

Comment by Matthieu Napoli [ 15/Jan/14 ]

Just for clarity (I answered this question in the pull request): no this is not fixed (see https://github.com/doctrine/doctrine2/pull/707#issuecomment-31564035).





[DDC-2405] Changing strategy generates bad query. Created: 19/Apr/13  Updated: 21/Apr/13

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

Type: Bug Priority: Major
Reporter: Van Rotemberg Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

For (unit, acceptance, functional) testing purpose I need to change the strategy of my GameStuff Entity class.

In previous version is was using php instruction below, but since doctrine orm 2.3, it doesn't work anymore.

$orm->getClassMetaData('Entities\GameStuff')->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);

will trigger:

Doctrine\DBAL\DBALException: An exception occurred while executing 'INSERT INTO vbank_accounts (game_id, updated_at, created_at) VALUES (?, ?, ?)' with params

{"1":1000010, "2":0,"3":"2013-04-19 17:16:05","4":"2013-04-19 17:16:05"}

:

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens



 Comments   
Comment by Benjamin Eberlei [ 20/Apr/13 ]

The problem is that changing ClassMetadata after generating it from the cache is not really supported and depends on the Internal State of other classes. Have you tried creating a completly new EntityManager and then directly setting this? It could be that the SQL for the entity was already generated inside Doctrine, with the ID Generator information at IDENTITY_AUTO.

Comment by Van Rotemberg [ 21/Apr/13 ]

> The problem is that changing ClassMetadata after generating it from the cache is not really supported

Yeah, it is a problem indeed, why set ticket status to resolved ?
Do you think it's normal to have a public method that trigger a fatal error ?

Please fix it or put setIdGeneratorType as private, or AT LEAST add a context exception ...

Comment by Marco Pivetta [ 21/Apr/13 ]

Almost every interaction with metadata outside the `loadClassMetadata` event will cause unexpected problems. I don't think throwing an exception there helps in any way.

Comment by Van Rotemberg [ 21/Apr/13 ]

@marco pivetta

The generation of the actual exception comes from DBALException on the query excetion and point a bad generated query (Invalid parameter number),
when the problem comes from setting ClassMetada, and concerns a problem of cache generated after loadClassMetadata.

Adding an exception is just the fast way pointing where the problem comes from and that "setting metadata after loadMetadata is not supported anymore". (It will spare developper's time that used to set metadata, but also help future contribution)

> Please fix it or put setIdGeneratorType as private, or AT LEAST add a context exception ...
Note: BTW, my favorite solution would be to fix it (re-generate cache, or edit cache, or disable cache or whatever)





[DDC-1924] Let SQLFilters know the query type it is being applied to Created: 13/Jul/12  Updated: 13/Jul/12

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

Type: Improvement Priority: Major
Reporter: Jan Knudsen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I'm making an access control system and would like to automatically filter all queries based current user, targetEntity type and query type. Query type is relevant as different permissions are needed by the user for SELECT, UPDATE, DELETE and INSERT queries.

I can access the first two things in my filter easily enough, but I cannot find a way to have the filter know what type of query the filter is being applied to.



 Comments   
Comment by Benjamin Eberlei [ 13/Jul/12 ]

The Filter API only makes sense for SELECT clauses. Doctrine itself does not use DQL to do updates internally, so you need to use other mechanisms (EventListener) to prevent this operations if they are not allowed for a user.

Comment by Jan Knudsen [ 13/Jul/12 ]

But I can make custom DQL to update rows and would like to automatically filter this too.

e.g. $em->createQuery("UPDATE SomeEntity se SET se.field = "updated!")->execute();

The lifecycle events preUpdate etc. are not called when doing custom DQL queries.

Maybe it is bad practice and discouraged to do updates, inserts and deletes as custom DQL queries, but I would like to ensure that the other people in my organization can't accidentally bypass the Access Control, even if they make use of such bad practice.

And if the filter API only makes sense for Select statements, why are filters applied to update/delete/etc. statements too?

Comment by Benjamin Eberlei [ 13/Jul/12 ]

Well, they are applied to DQL UPDATE/DELETE. But not not UPDATE/DELETE that works through the internals of Doctrine. So yes, you can use it to filter DQL DELETE/UPDATE, but doctrine does not do that internally.

So you have to have two strategies, a DQL/SQL Filter - and Lifecycle events.

Comment by Jan Knudsen [ 13/Jul/12 ]

Which is fine by me. I already implemented the checks using lifecycle events before opening this issue. The access control is automatically handled when using the entitymanager and not custom DQL.

Now I would also like to filter the custom DQL, but currently I can't, because as originally stated, the filter needs to know which type of query it is being applied to.





[DDC-1415] EventListener delegate on entity basis Created: 11/Oct/11  Updated: 20/Dec/11

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

Type: New Feature Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Comments   
Comment by Benjamin Eberlei [ 12/Dec/11 ]

Removed from master, as i dont like the api at all

Comment by Guilherme Blanco [ 20/Dec/11 ]

Updating fix version





[DDC-3115] UnitOfWok can't access proxies protected property Created: 04/May/14  Updated: 04/May/14

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

Type: Bug Priority: Major
Reporter: Machete Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

php5.5.11-1~dotdeb.1
debian 7.5 64bit
apache2
doctrine-orm-module 0.8.0


Attachments: PNG File doctrine-error.PNG    

 Description   

Running the code on different environments for a while now, I have never had any problems. Recently I installed the code onto a different server and I've been experiencing the following issue:

> Fatal error: Cannot access protected property DoctrineORMModule\Proxy_CG_\Page\Entity\PageRevision::$date in src/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2596

I am absolutely clueless, why this happens. It seems to be affecting only specific data rows, as you might reproduce here: http://de.serlo.org/pages

The field is defined as followed:

    /**
     * @ORM\Column(type="datetime", options={"default"="CURRENT_TIMESTAMP"})
     */
    protected $date;

However, the exact same database snapshot works fine here: http://ptr.serlo.org/pages

Attached you will find a screenshot of the datarows. The yellow ones mark each one working and one not working row.

I have no idea what the problem is here.



 Comments   
Comment by Marco Pivetta [ 04/May/14 ]

Discussed this on IRC - very tricky, seems like one of the servers has the reflection property not set to "accessible"

Comment by Machete [ 04/May/14 ]

Adding `$class->reflFields[$field]->setAccessible(true)` before line 2596 resolved this issue. Even after removing it, everything worked fine.

note to self:
> [18:23] <@ocramius> machete_: can you find out where that particular property is instantiated?
> [18:23] <@ocramius> should be in `ClassMetadataInfo::wakeUpReflection()` or such
> [18:25] <@ocramius> if you find that again, consider looking at locations in the code where `new ReflectionClass()` is instantiated





[DDC-3063] Unexpected behavior with 'WHERE NOT IN' and empty array Created: 01/Apr/14  Updated: 06/May/14

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Tim Stamp Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None
Environment:

CentOS, PHP 5.4, mysql



 Description   

I tried to set version to 2.4.0 but was prevented.

Assume the set 'n' contains 10 records, all with id > 0.

->andWhere('n.id NOT IN (:ids)')->setParameter('ids', [])
returns 0 records.

->andWhere('n.id NOT IN (:ids)')->setParameter('ids', [0])
returns 10 records.


 Comments   
Comment by Marco Pivetta [ 01/Apr/14 ]

This is a simple misunderstanding of how SQL IN() works

Comment by Tim Stamp [ 01/Apr/14 ]

You're right that its invalid SQL, but this is DQL. In SQL this would raise an error, in DQL it says nothing and returns nothing.

Isnt there a way to check if a statement has caused this error?

Comment by Marco Pivetta [ 01/Apr/14 ]

Tim Stamp yeah, when using IN() and NOT IN() you should actually check if the parameters are empty or not before adding the clause.

Comment by Steve Müller [ 01/Apr/14 ]

It's still weird that no error is raised by that. Tim Stamp can you check what SQL is generated by your query?

Comment by Steve Müller [ 01/Apr/14 ]

Hehe I think I got the problem. It might be DBAL related. See:

https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/SQLParserUtils.php#L140
https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/SQLParserUtils.php#L169

Looks like the implementing person did that by intention but don't ask me why.

Comment by Marco Pivetta [ 01/Apr/14 ]

Thats to avoid having an SQL statement like

SELECT * FROM foo WHERE bar IN()

, which is invalid.

Indeed, the NOT IN() case is not contemplated by that.

Comment by Steve Müller [ 01/Apr/14 ]

Just wondering if that kind of implementation isn't changing expectations because it looks like IN(NULL) will select all NULL rows then, even though this is not explicitly requested by the user. I don't care really TBH but this behaviour is not very transparent to the user. Personally I would like to see an error instead... Then at least I know what's going on and can fix that by additional checks instead.

Comment by Marco Pivetta [ 01/Apr/14 ]

Makes sense. Re-opening.

Comment by Steve Müller [ 01/Apr/14 ]

The question is if we can change this behaviour without breaking applications that rely on the current one. Because changing the code to throw an error breaks applications that insist on returning 0 rows for an empty array. I don't know what rules apply here concerning BC. What do you think Marco Pivetta?

Comment by Marco Pivetta [ 01/Apr/14 ]

Steve Müller existing apps should do following anyway:

if ($productIds) {
    $qb->andWhere('p.id IN (:productIds)')->setParameter('productIds', $productIds);
}

If they are not, that's most likely a bug in their codebase.

Comment by Steve Müller [ 01/Apr/14 ]

Agree. Was just wondering about what we can expect and what we can't expect.

Comment by Guilherme Blanco [ 21/Apr/14 ]

Steve Müller feel free to patch DBAL.
It's a bug, not a supported feature. If we have 2 tickets:
1- If I pass an empty array, I get nullable rows and I can't fix this
2- If I pass an empty array, it used to return nullable rows, now it returns nothing
Which one would you fix?

Comment by Tim Stamp [ 06/May/14 ]

Guilherme Blanco shouldn't both these use cases throw an exception, as both cases in MySQL would return an error?





[DDC-3188] Call to a member function getValue() on a non-object in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php Created: 24/Jun/14  Updated: 27/Jun/14

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

Type: Bug Priority: Major
Reporter: Daniel Imhoff Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.4.11
opensuse
apache2



 Description   

This is the line that causes the fatal error: https://github.com/doctrine/doctrine2/blob/v2.4.2/lib/Doctrine/ORM/UnitOfWork.php#L678

This is the association that is breaking it (i.e. reflFields[ 'user' ] is a non-object):

Tweet.php
/**
 * @ManyToOne(targetEntity="User")
 * @JoinColumn(name="user_id", referencedColumnName="id")
 *
 * @var User
 */
protected $user;

This is the pk of the referenced entity.

User.php
/**
 * @Id
 * @Column(name="id", type="bigint", nullable=false)
 *
 * @var int
 */
protected $id;

If an exception was thrown due to missing metadata information, I could catch it, but fatal errors due to this bug have been crashing our scripts and they've had to be manually restarted.

Let me know what other information is needed.

Full stack trace:

PHP 5. Doctrine\ORM\EntityManager->flush() our_code.php
PHP 6. Doctrine\ORM\UnitOfWork->commit() vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:389
PHP 7. Doctrine\ORM\UnitOfWork->computeChangeSets() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:297
PHP 8. Doctrine\ORM\UnitOfWork->computeScheduleInsertsChangeSets() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:703
PHP 9. Doctrine\ORM\UnitOfWork->computeChangeSet() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:404
PHP Fatal error: Call to a member function getValue() on a non-object in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 678



 Comments   
Comment by Marco Pivetta [ 24/Jun/14 ]

Did you actually validate your mappings?

Comment by Daniel Imhoff [ 24/Jun/14 ]

I did not validate the mapping. I did not know about the orm:validate-schema until just now. I will fix these errors and resubmit if there is still an issue.

Sorry about that, thanks.

Comment by Daniel Imhoff [ 24/Jun/14 ]

The tweet and user relationship is not in the list of invalid mappings.

Comment by Marco Pivetta [ 26/Jun/14 ]

Are User and Tweet in the same namespace?

Comment by Daniel Imhoff [ 27/Jun/14 ]

Yes, and I've since then used the FQNS. I would get a class not found error when validating schema.
This is something that I know can't really be debugged by you guys, I was just hoping for a little direction. We are using memcache to store our metadata, and we are clearing and regenerating the metadata during every deploy (it is not autogenerated). I'm now using a commit hash as the namespace of the metadata, so we'll see if this fixes the issue.

Comment by Marco Pivetta [ 27/Jun/14 ]

It looks like a typo (CasESensiTIViTy issue) to me.





[DDC-1698] Inconsistent proxy file name & namespace result in __PHP_Incomplete_Class when unserializing entities Created: 13/Mar/12  Updated: 25/Sep/13

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2, 2.2.1, 2.3, 2.4
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Benjamin Morel Assignee: Marco Pivetta
Resolution: Unresolved Votes: 2
Labels: proxy


 Description   

Starting with Doctrine 2.2, the Proxy classes have inconsistent naming with their file name, which raises problems with class autoloading.
For example, a class named Application\Model\User creates the following proxy class:

Application\Proxy\__CG__\Application\Model\User

This class is located in the following file:

Application/Proxy/__CG__ApplicationModelUser.php

But whe we serialize such an entity, then unserialize it in another session, the framework autoloader expects the class to be located in:

Application/Proxy/__CG__/Application/Model/User.php

But it is not.
As a result, a __PHP_Incomplete_Class is created instead of the expected proxy class.

I'm not sure whether this is an intended behavior, but I would assume this is a bug.



 Comments   
Comment by Benjamin Morel [ 13/Mar/12 ]

It looks like there is an even broader problem with the new _CG_ prefix; the PSR-0 standard for autoloading states that the underscores should be handled this way:

\namespace\package\Class_Name => {...}/namespace/package/Class/Name.php

Which means that in the above example, it could even expect the file to be located in:

Application/Proxy///CG///Application/Model/User.php

... which is far away from the actual location.
Upgrade to 2.2 broke this code, for us.

Comment by Benjamin Eberlei [ 14/Mar/12 ]

Proxy classes do not follow PSR-0. For the case unserializing objects we should provide an extra autoloader i guess.

See here how symfony does it https://github.com/doctrine/DoctrineBundle/blob/master/DoctrineBundle.php#L57

Comment by Benjamin Eberlei [ 14/Mar/12 ]

See https://github.com/doctrine/doctrine2/commit/9b4d60897dfc7e9b165712428539e694ec596c80 and https://github.com/doctrine/orm-documentation/commit/01381fae1ff3d4944086c7cfe46721925bf6ca15

Comment by Benjamin Morel [ 14/Mar/12 ]

Thanks for the quick fix, Benjamin.
However, I have to admit that I'm not fully happy with the fix, as we (and probably many others) are not using the Doctrine autoloader.
I supposed that the purpose of PSR-0 was precisely not to be tied to a particular autoloader implementation, and this benefit is lost with this version of Doctrine.

You mentioned in the doc that the proxies are not PSR-0 compliant "for implementation reasons"; as this was working fine before 2.2, could you please explain what requirement prevents Doctrine from keeping the previous naming convention?

Comment by Benjamin Eberlei [ 29/Mar/12 ]

In 2.1 the proxies are not PSR-0 compatible themselves, however their class naming is simpler.

In 2.2 we changed proxy names so that you can derive the original name of the proxy by searching for the _CG_ flag. This flag obviously contains the __ chars that some PSR autoloaders detect as directory seperators. I agree this is an unfortunate decision, but it was done this way.

I do think however that we can automatically register the proxy atuoloader (if not yet done) in EntityManager#create(). This would hide this fact from developers automatically.

Comment by Benjamin Morel [ 29/Oct/12 ]

@Benjamin Eberlei
In 2.3 we still have to manually call Autoloader::register() before unserializing entities that may contain proxies.
So EntityManager::create() still doesn't register it. Is there a plan to add this feature?

Comment by Benjamin Eberlei [ 06/Jan/13 ]

Benjamin Morel Not at the moment, seems too dangerous for me since it might produce race conditions. This should really be done in the bootstrap of the system.

We need to document this though.

Comment by Benjamin Morel [ 06/Jan/13 ]

Ok, thanks for your answer!

Comment by Matthieu Napoli [ 09/Sep/13 ]

Sorry to be a pain, but can the description of the task be updated:

  • Affects Version/s: should show all versions (or none) but not just 2.2, 2.2.1
  • Fix Version/s: should be blank

This is to make it clear that this bug is not resolved (since we are way past v2.2.2).

Thanks

Comment by Chris Hawkins [ 25/Sep/13 ]

Some additional documentation about this would be useful. I just spent some considerable time diagnosing an error related to restoring an entity from a cache. I wasn't able to find a mention of the need to call Autoloader::register until I found this page. It was resolved fairly quickly after I found this. For reference, I added this to my bootstrap:

ini_set('unserialize_callback_func', 'proxymissing');
function proxymissing( $name ) {
	if ( preg_match( '/^DoctrineProxies/', $name ) ) {
		\Doctrine\ORM\Proxy\Autoloader::register( PROXYPATH, 'DoctrineProxies' );
	}
}




[DDC-1695] SQLs for PostgreSQL case sensite tables/fields are wrongly generated Created: 09/Mar/12  Updated: 06/Aug/14

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1.6, 2.4.2
Fix Version/s: 2.1.7, 2.2.2
Security Level: All

Type: Bug Priority: Major
Reporter: Ignacio Larranaga Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PostgreSQL 9.x, Symfony 2


Attachments: Text File doctrine-2.1.6.patch     Text File SqlWalker.patch    

 Description   

The SQLs for case sensitive schemas in postgreSQL are wronly generated.

Example:
Schema:

CREATE TABLE "News" (
  "IdNews" serial NOT NULL,
  "IdUser" bigint NOT NULL,
  "IdLanguage" integer NOT NULL,
  "IdCondition" integer,
  "IdHealthProvider" integer,
  "IdSpeciality" integer,
  "IdMedicineType" integer,
  "IdTreatment" integer,
  "Title" character varying,
  "SmallText" character varying,
  "LongText" character varying,
  "PublishDate" timestamp with time zone,
  "IdxNews" tsvector,
  "Highlight" boolean NOT NULL DEFAULT false,
  "Order" integer NOT NULL DEFAULT 0,
  "Deleted" boolean NOT NULL DEFAULT false,
  "Active" boolean NOT NULL DEFAULT false,
  "UpdateToHighlighted" boolean DEFAULT false,
  CONSTRAINT "News_pkey" PRIMARY KEY ("IdNews" ));

Object (I added quotes trying to generate the SQLs quoted.:

<?php

namespace GlobalTreatments\ApplicationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="""News""")
 * @ORM\Entity
 */
class News
{
    /**
     * @var integer $idNews
     *
     * @ORM\Column(name="""IdNews""", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="""News_IdNews_seq""", allocationSize="1", initialValue="1")
     */
    private $idNews;

    /**
     * @var bigint $iduser
     *
     * @ORM\Column(name="""IdUser""", type="bigint", nullable=false)
     */
    private $idUser;

    /**
     * @var integer $idLanguage
     *
     * @ORM\Column(name="""IdLanguage""", type="integer", nullable=false)
     */
    private $idLanguage;

    /**
     * @var integer $idCondition
     *
     * @ORM\Column(name="""IdCondition""", type="integer", nullable=true)
     */
    private $idCondition;

    /**
     * @var integer $idHealthProvider
     *
     * @ORM\Column(name="""IdHealthProvider""", type="integer", nullable=true)
     */
    private $idHealthProvider;

    /**
     * @var integer $idSpeciality
     *
     * @ORM\Column(name="""IdSpeciality""", type="integer", nullable=true)
     */
    private $idSpeciality;

    /**
     * @var integer $idMedicineType
     *
     * @ORM\Column(name="""IdMedicineType""", type="integer", nullable=true)
     */
    private $idMedicineType;

    /**
     * @var integer $idTreatment
     *
     * @ORM\Column(name="""IdTreatment""", type="integer", nullable=true)
     */
    private $idTreatment;

    /**
     * @var string $title
     *
     * @ORM\Column(name="""Title""", type="string", nullable=true)
     */
    private $title;

    /**
     * @var string $smallText
     *
     * @ORM\Column(name="""SmallText""", type="string", nullable=true)
     */
    private $smallText;

    /**
     * @var string $longText
     *
     * @ORM\Column(name="""LongText""", type="string", nullable=true)
     */
    private $longText;

    /**
     * @var datetimetz $publishDate
     *
     * @ORM\Column(name="""PublishDate""", type="datetimetz", nullable=true)
     */
    private $publishDate;

    /**
     * @var tsvector $idxNews
     *
     * @ORM\Column(name="""IdxNews""", type="tsvector", nullable=true)
     */
    private $idxNews;

    /**
     * @var boolean $highlight
     *
     * @ORM\Column(name="""Highlight""", type="boolean", nullable=false)
     */
    private $highlight;

    /**
     * @var integer $order
     *
     * @ORM\Column(name="""Order""", type="integer", nullable=false)
     */
    private $order;

    /**
     * @var boolean $deleted
     *
     * @ORM\Column(name="""Deleted""", type="boolean", nullable=false)
     */
    private $deleted;

    /**
     * @var boolean $active
     *
     * @ORM\Column(name="""Active""", type="boolean", nullable=false)
     */
    private $active;

    /**
     * @var boolean $updateToHighlighted
     *
     * @ORM\Column(name="""UpdateToHighlighted""", type="boolean", nullable=true)
     */
    private $updateToHighlighted;

    /**
     * @var condition
     *
     * @ORM\ManyToOne(targetEntity="Condition")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdCondition""", referencedColumnName="""IdCondition""")
     * })
     */
    private $condition;

    /**
     * @var healthProvider
     *
     * @ORM\ManyToOne(targetEntity="HealthProvider")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdHealthProvider""", referencedColumnName="""IdHealthProvider""")
     * })
     */
    private $healthProvider;

    /**
     * @var language
     *
     * @ORM\ManyToOne(targetEntity="Language")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdLanguage""", referencedColumnName="""IdLanguage""")
     * })
     */
    private $language;

    /**
     * @var medicineType
     *
     * @ORM\ManyToOne(targetEntity="MedicineType")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdMedicineType""", referencedColumnName="""IdMedicineType""")
     * })
     */
    private $medicineType;

    /**
     * @var speciality
     *
     * @ORM\ManyToOne(targetEntity="Speciality")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdSpeciality""", referencedColumnName="""IdSpeciality""")
     * })
     */
    private $speciality;

    /**
     * @var treatment
     *
     * @ORM\ManyToOne(targetEntity="Treatment")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdTreatment""", referencedColumnName="""IdTreatment""")
     * })
     */
    private $treatment;

    /**
     * @var user
     *
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="""IdUser""", referencedColumnName="""IdUser""")
     * })
     */
    private $user;

    ....

}

DQL:

'SELECT n.smallText, n.publishDate ' .
'FROM News n ' .
	'INNER JOIN n.language la ' .
'WHERE la.languageCode = :languageCode ' .
'ORDER BY n.publishDate DESC'

Generated SQL:

SELECT "0_."SmallText" AS "SmallText"0, "0_."PublishDate" AS "PublishDate"1 FROM "News" "0_ INNER JOIN "Language" "1_ ON "0_."IdLanguage" = "1_."IdLanguage" WHERE "1_."LanguageCode" = ? ORDER BY "0_."PublishDate" DESC LIMIT 6

Notice there are unmattched " in the SQL.



 Comments   
Comment by Ignacio Larranaga [ 09/Mar/12 ]

If there is another approach to specify the table/column names are case sensitive in PGSQL please let me know.

Comment by Ignacio Larranaga [ 09/Mar/12 ]

Just to comment. I also tried the normal quoting.

Example: @ORM\Column(name="`IdNews`", type="integer", nullable=false)

And does not work too because of the same reason.

Comment by Ignacio Larranaga [ 09/Mar/12 ]

Hi, I generate this patch and seems to be working for me (at least what I'm testing right now).

I used ´ to quote tables and single attributes (not relationships) and the SQLs are correctly generated.

Comment by Ignacio Larranaga [ 09/Mar/12 ]

Adding a new patch for another files I need to change.

Comment by Benjamin Eberlei [ 11/Mar/12 ]

Formatted code

Comment by Benjamin Eberlei [ 11/Mar/12 ]

Fixed and merged into 2.1.x and 2.2 branches

Comment by Julian Aicardo [ 05/Aug/14 ]

This bug still unresolved for version 2.3.6-DEV included in Symfony 2.3.18.

The patches does not work with this version.

Generated query:

SELECT "0_.id AS id0, "0_."verFirmware" AS verfirmware1, "0_."idEstacion" AS idestacion2, "0_."fechaHora" AS fechahora3, "0_.global AS global4, "0_.directa AS directa5, "0_.difusa AS difusa6, "0_."tempSensDirecta" AS tempsensdirecta7, "0_.vbat1 AS vbat18, "0_.vbat2 AS vbat29, "0_.flags AS flags10, "0_."Estacion" AS estacion11 FROM "RegistroRS" "0_ WHERE "0_."idEstacion" = '1' AND "0_."fechaHora" >= '2014-02-01 03:00:00' AND "0_."fechaHora" <= '2014-08-01 03:00:00'

Notice there are unmattched " in the SQL.

Comment by Marco Pivetta [ 05/Aug/14 ]

Julian Aicardo why are you using 2.3.6-DEV? Shouldn't you use a stable version? Is the bug reproducible also with later versions?

Comment by Julian Aicardo [ 06/Aug/14 ]

After changing to version 2.4.2 the bug still there. The same SQL query was generated.

Comment by Julian Aicardo [ 06/Aug/14 ]

The error occurs when try to get an alias based on case sensitive table name, because the alias is generated with the first character of table's name which is ".
Ex:
Table: car Alias: c0_
Table: "Car" Alias: "0_

Is in file SqlWalker.php line 295 in Doctrine 2.4.4:

SqlWalker.php
public function getSQLTableAlias($tableName, $dqlAlias = '')
{
    $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : '';
        
    if ( ! isset($this->tableAliasMap[$tableName])) {
        $this->tableAliasMap[$tableName] = strtolower(substr($tableName, 0, 1)) . $this->tableAliasCounter++ . '_';
    }

    return $this->tableAliasMap[$tableName];
}




[DDC-2838] Leaky abstraction when applying Criteria to hydrated/non-hydrated PersistentCollection Created: 03/Dec/13  Updated: 20/Aug/14

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: brian ridley Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When applying a Criteria to a PersistentCollection that has been hydrated the field names must be camel case, if the collection has not yet been hydrated the field names must be underscore separated.

The github repo linked here contains a simplified testcase for the matrix of hydrated/non-hydrated entities and camel case/underscore separated fields.

https://github.com/ptlis/DoctrineTestcase



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

We can't check out an entire project just to test a bug.

Please write an actual functional test case that can be integrated into the Doctrine ORM test suite.

Comment by brian ridley [ 20/Aug/14 ]

Hi,

i'm happy to do so - i'll take a look at this over the weekend.





[DDC-3005] Events::postLoad fires without filled associations Created: 02/Mar/14  Updated: 19/Oct/14

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

Type: Bug Priority: Major
Reporter: Artur Eshenbrener Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Dependency
depends on DDC-3070 [GH-1001] [DDC-3005] Defer invoking o... Open

 Description   

When we load entities throw one dql query like this:

SELECT e, joined_link FROM Entity LEFT JOIN e.link joined_link

In event subscriber, subscribed to postLoad event for instances of Entity property "link" of entity does not contains fetched in same query joined entity, and does not contains proxy object.

Tell me if failing test case needed.



 Comments   
Comment by Marco Pivetta [ 02/Mar/14 ]

The postLoad event is fired without warranty that association entities/proxies will be set:

http://docs.doctrine-project.org/en/latest/reference/events.html#lifecycle-events

Comment by Artur Eshenbrener [ 03/Mar/14 ]

But why? This shounds like involuntary restriction, and I think it can be fixed. Will my PR with fix accepted, or collaborators don't want to change this behaviour?

Comment by Marco Pivetta [ 03/Mar/14 ]

Artur Eshenbrener triggering `postLoad` in the correct moment in time (when all dependencies are loaded) requires a lot of additional complexity to be inserted in various locations of the ORM.

Since `postLoad` is supposed to be used like `__wakeup` and in general for simple tasks, this kind of refactoring/rewrite would be an overkill.

Comment by Artur Eshenbrener [ 04/Mar/14 ]

> requires a lot of additional complexity to be inserted in various locations of the ORM.
Sounds like "It is very hard to implement, and no one want to do this"

> and in general for simple tasks, this kind of refactoring/rewrite would be an overkill.
Disagree with this. Why only simple? I need to deal with associations in this event. Without this I should inject whole EntityManager to my entity, but I dont want to do this.

And I forced to repeat the question: will PR with fix accepted or not?

Comment by Marco Pivetta [ 04/Mar/14 ]

Sounds like "It is very hard to implement, and no one want to do this"

Not really, the main problem here is performance, since hydration would have to be completely redesigned.
Yes, "too hard" is a good reason for something that is an edge case.

And I forced to repeat the question: will PR with fix accepted or not?

Sure thing! Just needs to avoid a massive rewrite though.

Comment by Marco Pivetta [ 04/Mar/14 ]

To give you some hints, Doctrine\ORM\Events::postLoad is triggered in https://github.com/doctrine/doctrine2/blob/15432fc55f83c2d6ce8d9b86fd3139dd2a4fc328/lib/Doctrine/ORM/UnitOfWork.php#L2788, and Doctrine\ORM\UnitOfWork#createEntity() is used by all the various hydrators internally.

To ensure that Doctrine\ORM\Events::postLoad is triggered after an entity is fully loaded, the various hydrators must trigger the events after being sure that all data has been set, and that the entity is "ready" for use. That's some copy-paste work :\

Comment by Artur Eshenbrener [ 04/Mar/14 ]

I think the entry point is here: https://github.com/doctrine/doctrine2/blob/15432fc55f83c2d6ce8d9b86fd3139dd2a4fc328/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php#L140,
so, copy-paste work is not needed )

Comment by Artur Eshenbrener [ 05/Apr/14 ]

PR is ready: https://github.com/doctrine/doctrine2/pull/1001

Comment by Doctrine Bot [ 19/Oct/14 ]

A related Github Pull-Request [GH-1001] was assigned:
https://github.com/doctrine/doctrine2/pull/1001

Comment by Doctrine Bot [ 19/Oct/14 ]

A related Github Pull-Request [GH-1001] was unassigned:
https://github.com/doctrine/doctrine2/pull/1001





[DDC-1283] Possible issue with PersistentCollection#getDelete/InsertDiff() Created: 21/Jul/11  Updated: 07/Sep/13

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

Type: Improvement Priority: Minor
Reporter: Glen Ainscow Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Using the following code, when you go from (1, 2) to (1), (2) is deleted as expected. However, if you go from (1, 2) to (2), (1) and (2) are deleted and (2) is then inserted. Is this the desired behaviour? (i.e. 2 extra queries)

$bracket->getTournamentLocations()->takeSnapshot();

$col = $bracket->getTournamentLocations()->unwrap();

$col->clear();

foreach ($form->getValue('tournamentLocations') as $id) {
    $col->add($em->getReference('Tournaments_Model_TournamentLocation', $id));
}

$bracket->getTournamentLocations()->setDirty(true);


 Comments   
Comment by Benjamin Eberlei [ 26/Jul/11 ]

First, you are using internal API therefore you are on your own anyways.

This is marked as improvment now, the functionality works, it may just be inefficient.

Comment by Guilherme Blanco [ 09/Dec/11 ]

Hi,

I'm marking issue as invalid because you're conceptually wrong.
What you're trying to do is telling that a collection of new entities is holded by a collection of Persistent entities.
The reference internally of PersistentCollection to ArrayCollection means a lot here.

Correct code would be you to regenerate the collection (a new ArrayCollection) and just assign it to setTournamentLocations($newCollection);

Does this explanation is enough for you?

Cheers,

Comment by Glen Ainscow [ 23/Dec/11 ]

Hi Guilherme,

If I do this:

$locations = new ArrayCollection();

foreach ($form->getValue('tournamentLocations') as $id) {
    $locations->add($em->getReference('Tournaments_Model_TournamentLocation', $id));
}

$bracket->setTournamentLocations($locations);

... then all the records are deleted, before adding the new records. This is inefficient and causes extra, unnecessary write operations.

Can't Doctrine perform diffs when persisting the collection, so that only the necessary deletes and inserts are executed?

Comment by Guilherme Blanco [ 13/Jan/12 ]

We could add it, but I don't think it worth the effort.
Main problem with this one is that we use C-level binary comparison to get the diff. That's what you entities/hash pointers are different.
We would have to write our own diff-comparator for both collections, which would probably slowdown the entire Doctrine.

I'd rather consider that it's not possible to be done at the moment, but I need much more investigation for that. This will be something that I'll probably only do when I look at this issue again with a lot of time (which is really hard to happen).

If you have some spare time, feel free to make some attempts.
Just don't forget to enable performance tests in Doctrine Unit Test suite.





[DDC-1081] Unnecessary JOIN when selecting ManyToMany/Join Table by ID. Created: 27/Mar/11  Updated: 28/Mar/11

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

Type: Improvement Priority: Minor
Reporter: David Reisch Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

With the schema:

 
Image
    @Id
    $id

Tag
    @Id
    $Id

Tag_Image
    @Id
    @OneToOne(targetEntity="Tag")
    @JoinColumn(name="tag")
    $tag

    @Id
    @OneToOne(targetEntity="Image")
    @JoinColumn(name="image")
    $image

Given the following DQL,

    SELECT img
    FROM Image 
    LEFT JOIN img.tags tag
    WHERE tag.id=:tag

Doctrine Generates this SQL

 
    SELECT i0_.id AS id1 
    FROM Image i0_ 
    LEFT JOIN Tag_Image t2_ 
        ON i0_.id = t2_.image 
    LEFT JOIN Tag t1_ 
        ON t1_.id = t2_.tag 
    WHERE t1_.id = 37

Which unncessarily joins against Tag, given that the foreign key Tag.id is also found in Tag_Image.tag.



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

This is not a bug, but expected behavior.

You can select against the alias if its on the owning side of the association:

SELECT img
FROM Image img 
WHERE img.tag=:tag

In this case it is not a left join though, if you want a left join you HAVE to join.

Comment by David Reisch [ 27/Mar/11 ]

There is no owning isde of the association, you can clearly see there is an association table/entity.

I can't understand how this behavior is expected. If no properties of Tag are selected for, there is no need to join against Tag since the id is already available via the association table.

Comment by Benjamin Eberlei [ 28/Mar/11 ]

I misread the mappings, sorry, i though its a @OneToOne but its actually an assocition entity with @OneToOnes.

Can you show me the Image::$tags mapping also?

Comment by David Reisch [ 28/Mar/11 ]

That is correct, thanks for taking another look at this.
Sorry I had forgotten to include that information.

Image
    /**
        @Id
    */
    $id

    /**
        @ManyToMany(targetEntity="Tag")
        @JoinTable(name="Tag_Image", 
                            joinColumns={@JoinColumn(name="image")},
                            inverseJoinColumns={@JoinColumn(name="tag")})
    */
    $tags
Comment by Benjamin Eberlei [ 28/Mar/11 ]

The targetEntity is wrong. I suppose it should be Image_Tag or not? If it should be Tag, then you don't need that Image_Tag entity at all.

In that case i have to check if you can use the shortcut notation, however it will again not work with the left join - only inner. This is an assumption the ORM makes and there is not yet code included for the optimization. This is not a bug, but an improvement ticket. The functionality works.

Comment by David Reisch [ 28/Mar/11 ]

No argument on the ticket type...

Ahh, I store some metadata in Tag_Image, which is why I manage it explicitly.

In any case thanks for looking at this.

Comment by Benjamin Eberlei [ 28/Mar/11 ]

If you change the targetEntity to Tag_Image then it might already be enough to get this working without another join.

Comment by David Reisch [ 28/Mar/11 ]

With this change, the original query is invalid:

    LEFT JOIN i.tags t
    WHERE t.id=:tag

Because i.tags of type Tag_Image has no field id

[Semantical Error] line 0, col 138 near 'id=:tag ': Error: Class domain\Tag_Image has no field or association named id

I attempt the logical modification:

    LEFT JOIN i.tags t
    WHERE t.tag=:tag

and get

SELECT i0_.id AS id0
FROM Image i0_ 
LEFT JOIN Tag_Image t1_ ON i0_.id = t1_.image 
LEFT JOIN Tag_Image t1_ ON t1_.id = t1_.tag 
WHERE t1_.tag = 37

SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 't1_





[DDC-450] Add TableGenerator Implementation Created: 20/Mar/10  Updated: 13/Feb/12

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-ALPHA4
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Benjamin Eberlei Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 2
Labels: None

Issue Links:
Dependency
depends on DBAL-223 Add DBAL TableGenerator Resolved

 Description   

The TableGenerator Id Generator is not yet implemented, here is some code i came up with:

class TableGenerator extends AbstractIdGenerator
{
    private $_tableName;
    private $_sequenceName;
    private $_allocationSize;
    private $_nextValue;
    private $_maxValue;

    public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10)
    {
        $this->_tableName = $tableName;
        $this->_sequenceName = $sequenceName;
        $this->_allocationSize = $allocationSize;
    }

    public function generate(EntityManager $em, $entity)
    {
        if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
            // Allocate new values
            $conn = $em->getConnection();
            if ($conn->getTransactionNestingLevel() == 0) {

                // use select for update
                $sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
                $currentLevel = $conn->fetchColumn($sql);
                if ($currentLevel != null) {
                    $this->_nextValue = $currentLevel;
                    $this->_maxValue = $this->_nextValue + $this->_allocationSize;

                    $updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
                        $this->_tableName, $this->_sequenceName, $this->_allocationSize
                    );
                    
                    if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
                        // no affected rows, concurrency issue, throw exception
                    }
                } else {
                    // no current level returned, TableGenerator seems to be broken, throw exception
                }
            } else {
                // only table locks help here, implement this or throw exception?
                // or do we want to work with table locks exclusively?
            }
        }
        return $this->_nextValue++;
    }
}


 Comments   
Comment by Guilherme Blanco [ 04/Aug/10 ]

Already merged into core.

Comment by Benjamin Eberlei [ 04/Aug/10 ]

But it is not enabled yet Plus we need tests to verify this works in high concurrency enviroments and does not pass the same id twice.

Furthermore the DAtabase Platform Methods are completly missing. No implementations yet.

Comment by Benjamin Eberlei [ 04/Aug/10 ]

Schema-Tool support is also missing.





[DDC-3087] Entity code generation skip setters Created: 15/Apr/14  Updated: 07/Jun/14

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

Type: Improvement Priority: Minor
Reporter: Flip Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When executing `orm:generate-entities` to generated methods, do not generate setters when entity is readOnly `@ORM\Entity(readOnly=true)`



 Comments   
Comment by Christopher Stea [ 06/Jun/14 ]

I would like to see this feature but at the field level: Maybe my entity has a timestamp property that is auto-generated (uses Timestampable). I want to be able to have a getter but not a setter. Right now if I doctrine:generate and remove the setter function, it is re-created any time i re-run doctrine:generate.

I would suggest having @ORM/readonly as an available setting for properties.

Comment by Marco Pivetta [ 06/Jun/14 ]

I think this use case is simply a customization that should be applied by coding, and not via the generator.

Comment by Christopher Stea [ 07/Jun/14 ]

I have made the required edits and created a pull request:

https://github.com/doctrine/doctrine2/pull/1052
http://www.doctrine-project.org/jira/browse/DDC-3157

In the case of the original request, users can use readonly on every property in the table if they chose to make the entire entity read-only.

Comment by Doctrine Bot [ 07/Jun/14 ]

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

Comment by Marco Pivetta [ 07/Jun/14 ]

See comments on DDC-3157

Comment by Flip [ 07/Jun/14 ]

The PR by Christopher Stea adds a readonly annotation for properties. This ticket is about using the readonly annotation on the class (ORM\Entity) which is already in Doctrine. And just modify the code generator a little bit to skip the setters. Please reopen!!!

Comment by Marco Pivetta [ 07/Jun/14 ]

The PR introduces metadata used solely for the purpose of code generation.

Comment by Flip [ 07/Jun/14 ]

Yes that's not what THIS ticket is about, so please reopen because the PR is related, but not at all a solution to this ticket.

Comment by Marco Pivetta [ 07/Jun/14 ]

Hmm, makes sense. Re-opening then.





[DDC-567] Foreign Key to Unique Field Update Failure Created: 03/May/10  Updated: 08/Oct/12

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA2
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Trivial
Reporter: Michael Ridgway Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 2
Labels: None

Attachments: File DDC567Test.php    

 Description   

I am getting an error: 'Notice: Undefined index: sysname in ./libraries/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 434' when I try to flush a change to a property that references a unique field on another object.

From poking around in the _prepareUpdateData function, it seems that it only allows you to use identifier fields:

$newValId = $uow->getEntityIdentifier($newVal);

..

$result[$owningTable][$sourceColumn] = $newValId[$targetClass->fieldNames[$targetColumn]];

I'll see if I can get a test case for this set up.



 Comments   
Comment by Roman S. Borschel [ 03/May/10 ]

Hi. That is right. Foreign keys (join columns) must point to primary keys, not arbitrary other columns, whether they're unique or not, Doctrine does not know.

In other words, joinColumn must always refer to an identifier/pk. I'm not sure but I think anything else would be a pretty strange relational model, too, but there may be usecases we have not yet encountered.

I'm afraid this will not be possible and would be very hard to implement. Of course if somebody has a patch we happily accept it (after reviewing).

Leaving this open in the case somebody wants to work on it.

Comment by Michael Ridgway [ 03/May/10 ]

A minimal test case. Removing the first flush produces the same error, so this seems to be a bug on inserts as well.

Comment by Roman S. Borschel [ 03/May/10 ]

Its not really a bug but rather a new feature This was not intended to work so far.

Comment by Michael Ridgway [ 03/May/10 ]

Ah, ok. Maybe it didn't work before. I don't know where I got the idea that it did.

Thanks.

Comment by Michael Ridgway [ 03/May/10 ]

Oops, closed it before I noticed you said you wanted to leave it open.

Comment by Roman S. Borschel [ 03/May/10 ]

Thanks for the testcase though, it is useful. In your concrete example, is it not an option to make the sysname the @Id ?

Comment by Michael Ridgway [ 03/May/10 ]

Yes. That is definitely the way it should be done in this case. I can't really think of a case to have a reference to a unique key while still having an Id on it, except when you're working with an existing, poorly designed database (which is our case).

The reason I assumed this was possible is that the references actually work for lazy loading, but as soon as you start changing the references it throws this error.

Comment by Roman S. Borschel [ 14/May/10 ]

Lowering priority.

Comment by Thomas Subera [ 08/Oct/12 ]

although we would also need this i would suggest adding an error message if the associated column is not found in $newValId. (class BasicEntityPersister.php _prepareUpdateData)

otherwise the field is populated with null leaving the developer debugging an hour :-/

thx





Generated at Thu Oct 23 14:28:21 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.