[DDC-222] Create unit tests for CLI components Created: 22/Dec/09 Updated: 30/Oct/10 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-ALPHA3 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Task | Priority: | Critical |
| Reporter: | Roman S. Borschel | Assignee: | Guilherme Blanco |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Comments |
| Comment by Roman S. Borschel [ 19/May/10 ] |
|
Whats the status here? Do we have any? |
| Comment by Guilherme Blanco [ 19/May/10 ] |
|
Since we moved to Symfony Console I don't think this is needed anymore. I'm closing the ticket due to this. Reopen if you have any other comment. |
| Comment by Benjamin Eberlei [ 20/May/10 ] |
|
I think we do need some basic functional tests of our Commands, they have been subject to many bugs in the past becaues they are not tested. |
| Comment by Benjamin Eberlei [ 19/Jun/10 ] |
|
Fixed another fatal error in the command due to missing namespace dependency. We need tests for all the commands, there have been dozens of issues on these things so far. This commit shows a simple approach on how testing is easily possible for symfony commands: http://github.com/doctrine/doctrine2/commit/51e6681934a7cf4448b85c5670c04045f66c6056 |
| Comment by Roman S. Borschel [ 26/Aug/10 ] |
|
Can we expect some more tests for beta4 or is it unlikely that you find the time? Should we move this further back or does someone else want to step in? |
[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-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-1698] Inconsistent proxy file name & namespace result in __PHP_Incomplete_Class when unserializing entities Created: 13/Mar/12 Updated: 06/Jan/13 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.2, 2.2.1 |
| Fix Version/s: | 2.2.2 |
| Security Level: | All |
| Type: | Documentation | Priority: | Major |
| Reporter: | Benjamin Morel | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Irrelevant |
||
| Description |
|
Starting with Doctrine 2.2, the Proxy classes have inconsistent naming with their file name, which raises problems with class autoloading. 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. 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. |
| 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. 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 |
| 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! |
[DDC-2210] PHP warning in ProxyFactory when renaming proxy file Created: 20/Dec/12 Updated: 28/Mar/13 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Major |
| Reporter: | Matthieu Napoli | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Windows |
||
| Description |
|
Getting a PHP Warning: rename(**/models/Proxies_CGAF_Model_Component_Group.php.50d2dd2c079bb9.35271255,**/models/Proxies__CG_AF_Model_Component_Group.php): in ProxyFactory line 194. I haven't more information in the warning. This is the moment when the ProxyFactory writes the proxy to a temporary file and then tries to rename the temp file to the correct file. This warning appears randomly, but mostly on pages with lots of concurrent AJAX requests. I guess this happens because several requests try to write the proxy file at the same time. I get this warning but the app works fine. This happens in dev environment, on a Windows machine. I don't know why rename generates a warning, it should just return false... The doc doesn't say anything about warnings (except for long file names, but I checked even with the full path this is around 135 characters, not 255). |
| Comments |
| Comment by Benjamin Eberlei [ 22/Dec/12 ] |
|
Thats why you shouldn't generate proxies at runtime. The problem happens on windows, because the atomic rename operation doesn't work as perfectly there as on linux. We cannot fix this in Doctrine. |
| Comment by Matthieu Napoli [ 24/Dec/12 ] |
|
Benjamin Eberlei What do you mean "you shouldn't generate proxies at runtime"? I'm not in production, this is in dev. And I'm using the default configuration. What I don't understand is why will Doctrine regenerate proxies on every request? The warning is reproductible, and even when no PHP entity has been touched. |
| Comment by Matthieu Napoli [ 27/Dec/12 ] |
|
Benjamin Eberlei To simplify my previous message (I don't want to bury you under questions) I'll sum it up like that: What can I do? Thanks! |
| Comment by Matthieu Napoli [ 28/Feb/13 ] |
|
Benjamin Eberlei ping: what can be done? Can we suppress the error with @rename($tmpFileName, $fileName); ? https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Proxy/ProxyGenerator.php#L287 I can make a PR if you think that's a valid solution. |
| Comment by Marco Pivetta [ 28/Feb/13 ] |
|
Matthieu Napoli no, if you have warnings, please disable them via ini setting. With error suppression there, we may have further problems identifying more serious issues. About proxy generation: that happens EVERY time in dev environments. Generate them once and disable it afterwards. |
| Comment by Matthieu Napoli [ 28/Feb/13 ] |
|
Marco Pivetta OK I can disable the auto generation then (I'll have to remember to regenerate them when I edit the model). Thanks for the feedback Is that possible to make those proxies generate only if the entity file has been modified since the last generation? (only asking if can and should be done, I can look for implementing it myself if that's the case) |
| Comment by Marco Pivetta [ 28/Feb/13 ] |
|
Matthieu Napoli that would be very obnoxious when changing entities often. I wouldn't do that (generating only if not already available) |
| Comment by Matthieu Napoli [ 28/Feb/13 ] |
|
Marco Pivetta Yes but for now they are regenerated at every request when in dev mode (at least with the default configuration http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/configuration.html#obtaining-an-entitymanager) Which one is worse: generating every proxy class at every request, or generate only those which changed (in dev environment of course, not prod)? If neither of these options are good (i.e. auto generation should be disabled), I don't understand why the docs say to enable auto generation when in dev environment. |
| Comment by Marco Pivetta [ 28/Feb/13 ] |
|
Matthieu Napoli that's because in dev environments you shouldn't care about that one exception (usually happens when you got concurrent requests). It is worse to generate only on changes: that's a lot of additional checks, variables to keep in memory and additional logic that is not needed. Let's keep it as it is (generating at each request) for dev environments: works fine Another (eventual) solution for dev environments would be not to write the proxy file, but to eval it. |
| Comment by Matthieu Napoli [ 28/Feb/13 ] |
|
eval it would be a good solution IMO, no more "woops the directory is not writable" and it's more neutral for the user filesystem (but not as easy to debug). But OK, I see what you mean, it works let's keep it that way. Actually the problem on my setup is that PHP errors are turned into exceptions, so on an (poorly designed) AJAX treeview (lots of nodes to load => lots of requests), I end up with some nodes not loaded because of the exception. And it feels weird to either silently log all PHP warnings or silently ignore the specific warning for the rename. |
| Comment by Marco Pivetta [ 28/Feb/13 ] |
|
Matthieu Napoli I'd go with `eval` then. Needs refactoring of the abstract proxy factory and of the proxy generator (proxy generator should no longer write files). |
| Comment by Marco Pivetta [ 28/Feb/13 ] |
|
Re-opening: the proxy factory could directly `eval()` the produced proxy code. The ProxyGenerator should no longer write the generated files to disk automatically. |
| Comment by Matthieu Napoli [ 28/Mar/13 ] |
|
I've opened a PR: https://github.com/doctrine/common/pull/269 |
[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 ? 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), 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 ... |
[DDC-2052] Custom tree walkers are not allowed to add new components to the query Created: 02/Oct/12 Updated: 14/May/13 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | 2.4 |
| Type: | Improvement | Priority: | Major |
| Reporter: | Łukasz Cybula | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql | ||
| Description |
|
Custom tree walkers have freedom in modifying the AST but when you try to add a new query component (i.e. new join in walkSelectStatement() ) to the AST then the SqlWalker throws an exception because it does not has the new component in its _queryComponents array. I see two possible ways to resolve this: |
| Comments |
| Comment by Benjamin Eberlei [ 06/Oct/12 ] |
|
Ok this is much more complicated to allow then i thought. The problem is that the QueryComponents are passed by value, as an array, not by reference. That prevents changing them because this change wouldn't be visible in the output walker. I can add a method to allow this in the OutputWalker for now, but generally this requires a bigger refactoring on the Query Components. |
| Comment by Benjamin Eberlei [ 06/Oct/12 ] |
|
Added setQueryComponent() in SQL Walker to allow modification in output walker. |
| Comment by Łukasz Cybula [ 08/Oct/12 ] |
|
I'm afraid that this doesn't solve the initial problem at all. I'll try to describe it in more details to show what I mean. Suppose we have two doctrine extensions each of which contain its own tree walker. Each of these tree walkers need to modify AST and add new component to it (joined with some component already existing in the query). The first problem is that each tree walker has its own queryComponents array which is not passed between them, although they not necessary need to use queryComponents - they could use only AST. The second, bigger problem is that the Parser class does not know anything about modifications of queryComponents in tree walkers and cannot pass modified version to the OutputWalker. The goal of submitting this issue was to allow adding new components to the query in tree walkers which is not achievable by your fix. I think it may be the first step in the right direction. Maybe TreeWalkerAdapter should have public method getQueryComponents() which would be used by the Parser to pass modified queryComponents between different tree walkers and finally to the OutputWalker ? This would not break backward compatibility and solve this issue. What do you think about it? |
| Comment by Łukasz Cybula [ 08/Oct/12 ] |
|
I've tried to implement the solution mentioned in previous comment but it's also not so clean and easy as I thought. Each tree walker (including TreeWalkerChain) would have to implement getQueryComponents() and setQueryComponent($alias, array $component) methods. The same with SqlWalker, so the TreeWalker interface should have these methods, which would break BC in some way (walkers that do not inherit from SqlWalker or TreeWalkerAdapter will fail to compile). So maybe my first solution (PR #464) is not so bad for now? In the future queryComponents could be replaced by a special object or could be passed by a reference to allow modifications. |
| Comment by Benjamin Eberlei [ 09/May/13 ] |
|
Marked as improvement as its not a bug. A solution might probably implement an object holding all the QueryComponent, implementing ArrayAccess. So that way the state can be shared. |
| Comment by Marco Pivetta [ 14/May/13 ] |
|
Just hit this while developing an ast walker... Will look into it too since I need it more than soon. |
| Comment by Marco Pivetta [ 14/May/13 ] |
|
As a VERY UGLY workaround, I used a static variable and a custom sql walker in combination with my AST walker. namespace Comcom\Versioning\ORM\Query; use Doctrine\ORM\Query\SqlWalker; class WorkaroundSqlWalker extends SqlWalker { public function __construct($query, $parserResult, array $queryComponents) { parent::__construct($query, $parserResult, $queryComponents); foreach (VersionWalker::$additionalAliases as $alias => $value) { $this->setQueryComponent($alias, $value); } } } |
[DDC-2461] [GH-673] Namespace based command names Created: 17/May/13 Updated: 17/May/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: | Doctrine Bot | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
This issue is created automatically through a Github pull request on behalf of hell0w0rd: Url: https://github.com/doctrine/doctrine2/pull/673 Message: Symfony console supports auto completion: |
| Comments |
| Comment by Doctrine Bot [ 17/May/13 ] |
|
A related Github Pull-Request [GH-673] was closed: |
| Comment by Marco Pivetta [ 17/May/13 ] |
|
BC break without advantages |
| Comment by Doctrine Bot [ 17/May/13 ] |
|
A related Github Pull-Request [GH-673] was reopened: |
[DDC-2235] Single table inheritance discriminator in WHERE when using arbitrary join syntax Created: 11/Jan/13 Updated: 23/May/13 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Jordi Forns | Assignee: | Alexander |
| Resolution: | Unresolved | Votes: | 3 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
The condition on the discriminator column is placed in the WHERE clause when using arbitrary join syntax, which renders LEFT JOINs useless. Given these classes:
$qb->select('a.id AS idA, b.id AS idB')
->from('\Entity\A', 'a')
->leftJoin('\Entity\B1', 'b', \Doctrine\ORM\Query\Expr\Join::WITH, 'a.something=b.something');
And the SQL Doctrine generates is something like this:
SELECT a.id, b.id FROM a LEFT JOIN b ON (a.something=b.something) WHERE b.type IN ('1', '2', '3')
The problems is that the WHERE condition makes the left join useless. The condition on the discriminator column should be placed in the JOIN clause to avoid the problem. |
| Comments |
| Comment by Ondrej Hlavaty [ 10/Feb/13 ] |
|
Can this be somehow worked around? If not, it is really serious problem... |
| Comment by Jordi Forns [ 18/Feb/13 ] |
|
I couldn't find any workaround. |
| Comment by Michel Salib [ 22/Mar/13 ] |
|
Easier way to workaround right now, is to declare a OneToMany from class A to class B on a protected field (no need of getter or setter). That way you can do classic join via relationship transversing and then the condition will be placed in the ON part of the query. |
| Comment by Yuta Konishi [ 01/Apr/13 ] |
|
I could access with below codes. You should use RAW SQL it is easy solution I guess. good luck. $qb = $em->createQueryBuilder();
$qb->select('a, b')
->from('YourEntity1', 'a')
->leftJoin('YourEntity2', 'b', \Doctrine\ORM\Query\Expr\Join::WITH, 'a.id = b.relationId');
$raw_sql = $qb->where(
$qb->expr()->in('a.relationId', $ids)
)
->orderBy('a.updatedAt', 'DESC')
->setMaxResults(10)
->getQuery()->getSQL();
$conn = $em->getConnection();
$stmt = $conn->query($raw_sql);
/* $stmt->fetchAll(); // access as Array */
|
| Comment by Benjamin Eberlei [ 04/Apr/13 ] |
|
Assigned to Alexander |
| Comment by Benjamin Eberlei [ 14/Apr/13 ] |
|
Duplicate of DDC-1940 |
| Comment by Jordi Forns [ 22/Apr/13 ] |
|
Benjamin: this bug doesn't seem to be a dupe of DDC-1940. Actually that issue doesn't seem to be a bug at all. As a reminder, the problem in this issue is that when performing arbitrary left joins on entities that are part of a class hierarchy, the discriminator condition is placed in the where clause instead of the join clause. This means that rows that could not be joined will have null values in the discriminator column and thus will not be returned because of the where condition (which will contain something like " where x.discriminator in (1,2,3) "). |
| Comment by Tom Arnfeld [ 27/Apr/13 ] |
|
Has this issue been resolved elsewhere? From reading over DDC-1940 it doesn't seem to be a duplicate at all. I'm experiencing the same problem as Jordi and can't seem to find a solution. Is there any particular reason the `IN ()` predicate is not a part of the join, but instead placed in the main `WHERE` clause? |
| Comment by Tom Arnfeld [ 28/Apr/13 ] |
|
I've been looking into the root cause of this bug (or feature..) to try and understand why it's happening, and after trying various possible fixes (a little hard without full understanding of the Doctrine/Query internals) I've ended up with a fix that seems to work well for my use case, at least. I've not run any of the unit tests (I plan to, and may adjust my fix based on that) but the top revision is my change... https://gist.github.com/tarnfeld/a6bb50ec707c7af1c5dc/revisions Would love some feedback. Pull request here: https://github.com/doctrine/doctrine2/pull/656 |
| Comment by Jordi Forns [ 29/Apr/13 ] |
|
Tom's fix moves the condition of the discriminator column to the LEFT JOIN, which is exactly what was needed. Alexander: could you please give it a look? |
| Comment by Jordi Forns [ 23/May/13 ] |
|
Tom's proposal seems to fix the issue. |
[DDC-1283] Possible issue with PersistentCollection#getDelete/InsertDiff() Created: 21/Jul/11 Updated: 20/Sep/12 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | 2.1 |
| Fix Version/s: | 2.4 |
| 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. 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. 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. |
[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. 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
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
|
[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: |
|
||||||||
| 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 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-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: |
|
| 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 |
| 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 |