[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-821] Consider adding Query-Join as another join method for DQL Created: 29/Sep/10 Updated: 29/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Marc Hodgins | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Description |
|
Some ORM systems support an alternative to fetch-join queries, called a "query-join". See http://www.avaje.org/ebean/introquery_joinquery.html. A query-join accomplishes the same as a fetch-join (hydrating a larger object graph across all associations types) but executes more than one SQL query in sequence in order to hydrate the requested portions of the graph in a result set. The first query retrieves data from the base entity/table and the next queries retrieve the data for the requested associations. In some cases this approach is more efficient to a fetch-join: (1) No data duplication in the SQL result as occurs in a fetch-join on to-many associations. Instead, this data is loaded through a second query. This saves network traffic, memory and general overhead in hydrating the returned results. In the case where large TEXT data is included in result sets, the savings here may be substantial. (2) setFirstResult() and setMaxResult() are again effective (for pagination) and more importantly more efficient on these query-joins. The current DoctrineExtension solution to enable pagination on fetch-joins requires a series of queries to determine the target primary keys of the root entity of the query. The primary key lookup query requires DISTINCT or GROUP BY – which often triggers filesorts, temporary tables, etc (at least on MySQL) and greatly slows down the query. Query joins would not require this. Possible implementation example: // existing fetch-join $query = $em->createQuery('SELECT c, o FROM Customers c JOIN c.orders o'); $query->setFirstResult(10)->setMaxResult(20); // doesn't do what you'd hope it would do, no ability to use this for pagination $customersAndOrders = $query->getResult(); // array of Customer objects with Orders hydrated // proposed query-join $query = $em->createQuery('SELECT c, o FROM Customers c QUERY JOIN c.orders o'); $query->setFirstResult(10)->setMaxResult(20); // now works for pagination $customersAndOrders = $query->getResult(); // array of Customer objects with Orders hyrdated // this would execute a series of queries -- i.e. in SQL // SELECT ... FROM customers LIMIT 10, 20 // SELECT ... FROM orders WHERE customer_id IN (.....) and/or, could there be a way to trigger a "query-join" against an existing array of entities? for example $query = $em->createQuery('SELECT c FROM Customers c'); // single query to fetch customers
$customers = $query->getResult(); // array of Customer objects
$em->join($customers, 'orders'); // fetch and hydrate the 'orders' association on each Customer using a single query
Perhaps at some point in the future Doctrine/DBAL could even make use of asynchronous queries (i.e. mysqlnd supports this) to allow these query-joins to run in parallel and the result would be more efficient paginated resultsets. Thoughts/feedback? |
| Comments |
| Comment by Benjamin Eberlei [ 30/Sep/10 ] |
|
There is another approach for this using several subqueries to build an IN clause, the Paginator extension supports this: http://github.com/beberlei/DoctrineExtensions I rather go the extension approach than changing the DQL for this feature. |
| Comment by Benjamin Eberlei [ 30/Sep/10 ] |
|
I just saw your second example, that is rather cool though and gets +1 from me. I had the same idea for "not initialized proxies", i.e. $em->getUnitOfWork()->initializeProxies('Customer');
|
| Comment by Marc Hodgins [ 29/Dec/10 ] |
|
Second example is a duplicate of |
[DDC-810] Issue with detaching entities and updating when using change notification Created: 17/Sep/10 Updated: 04/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | 2.0-BETA4 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Jonathan H. Wage | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
More information coming soon. Attaching a test case |
| Comments |
| Comment by Benjamin Eberlei [ 20/Sep/10 ] |
|
From reading the issue i know what the bug is, indeed this sucks. |
| Comment by Roman S. Borschel [ 28/Sep/10 ] |
|
@Jon: Any more information coming? @Benjamin: Can you summarize the essence of the issue shortly? |
| Comment by Benjamin Eberlei [ 29/Sep/10 ] |
|
@Roman: The UnitOfWork (may) still be pushed as a listener into that entity, and still recieve noticies of update. Which may throw notices because the oid hashes are removed everywhere. Additionally you cant serialize the thing because you still got the UoW inside there. |
| Comment by Jonathan H. Wage [ 04/Oct/10 ] |
|
I don't have anymore information currently. The issue was relayed to me. I will try and find some more information and report back. |
| Comment by Benjamin Eberlei [ 03/Apr/11 ] |
|
There is no way to "fix" this issue, i am turning it into a feature request. There needs to be a "postDetach" event that is triggered where the developer can detach the change notification objects. |
[DDC-1285] Select by multiple ids Created: 22/Jul/11 Updated: 11/Jan/13 |
|
| Status: | In Progress |
| Project: | Doctrine 2 - ORM |
| Component/s: | Mapping Drivers, ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Serge Smertin | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Description |
|
How do you look at adding findByIds(array $ids) to EntityManager and UnitOfWork? This would allow fetching multiple entities from a database at one request and would be very useful for caching - there would be even some kind of IdentityMap kept in memcached or any other caching engine, that supports multiple id retrieval: i've been using such an architecture in multiple projects and it turned out to be very effective. There were two basic methods - findIdsByFilter(array $filter) and findEntitiesByIds(array $ids). The latter one had a caching proxy, replicating entities to a cache storage. If this idea proceeds - I'd be glad to cover it with more details. This topic on StackOverflow could also help: |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-1264] Add more math related DQL funcs (trig, round, stuff?) Created: 09/Jul/11 Updated: 09/Jul/11 |
|
| Status: | Open |
| 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 | ||
[DDC-1262] Have proxies copy docblocks aswell Created: 09/Jul/11 Updated: 09/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0.6, 2.1, Git Master |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Whenever a Proxy is generated it does not copy the docblocks. This means when you do something like "$refl = new ReflectionObject($proxy)" you might be in trouble. However if we add docblocks then we have to make sure that proxies do not magically appear as entities by throwing an exception in the AnnotationDriver. |
[DDC-1229] generate entity interactive dialog: id column Created: 27/Jun/11 Updated: 28/Jun/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Tools |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | David Buchmann | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
according to Stof, this bug https://github.com/sensio/SensioGeneratorBundle/issues/21 comes from the doctrine tools implementation: in the dialog, i first specified that i want a field id of type integer. the result was [Doctrine\ORM\Mapping\MappingException] Duplicate definition of column 'id' on entity 'Liip\DemoBundle\Entity\Event' in a field or discriminator column mapping. and no file was created. The dialog should tell me i can not create a field named id. (Or better ask first if i want my id column named id or something else.) It would be nice if it would write some file even if its not valid, with a warning on top. As it is, i lost all my work of specifying fields. (Luckily was just playing around) |
| Comments |
| Comment by Benjamin Eberlei [ 28/Jun/11 ] |
|
not a bug, its a feature (though a dumb one). Improvement in a next version. |
[DDC-1219] Remove dependancy on Collection interface in Domain Objects Created: 21/Jun/11 Updated: 04/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | André R. | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Short: This issue is all about being able to use doctrine with naked domain objects without any use of doctrine classes. Seems like some of the UnitOfWork code is cable of handling other types of arrays, like: // If $actualData[$name] is not a Collection then use an ArrayCollection.
if ( ! $actualData[$name] instanceof Collection) {
$actualData[$name] = new ArrayCollection($actualData[$name]);
}
But in __cascade* functions this is not the case in all but two: if ($relatedEntities instanceof Collection) {
if ($relatedEntities instanceof PersistentCollection) {
// Unwrap so that foreach() does not initialize
2 however have: if (($relatedEntities instanceof Collection || is_array($relatedEntities))) {
if ($relatedEntities instanceof PersistentCollection) {
// Unwrap so that foreach() does not initialize
Would it be an idea to do "instanceof Traversable" instead of " instanceof Collection"? |
| Comments |
| Comment by André R. [ 21/Jun/11 ] |
|
Note: If the fist code block is always performed before the last 2 blocks then there is no issue here, just a need to make it more clear in Doc that this is possible but that you should not rely custom implementation as PersistentCollection will be injected when loaded from db. |
[DDC-1200] Derived Id Generator Created: 09/Jun/11 Updated: 09/Nov/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | Git Master |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 3 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
For usage with the foreign key as primary key features described in |
| Comments |
| Comment by Daniel Lima [ 09/Nov/11 ] |
|
When this will be fixed? I think this is related to http://groups.google.com/group/doctrine-user/browse_thread/thread/7e1cfa9c4c99af31 |
[DDC-1178] Have access to "original" metadata in events subscribed to loadClassMetadata Created: 27/May/11 Updated: 27/May/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Mapping Drivers |
| Affects Version/s: | 2.x |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Miha Vrhovnik | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
If you subscribe to loadClassMetadata you will usually modify the metadata for some classes. My proposal would be to add function get(Original|Raw)MappingData into interface Doctrine\ORM\Mapping\Driver\Driver which would either return raw data or data in a object specific for that Driver or null if it doesn't make sense for that driver. Please note, that when loading from e.g XmlDriver we should return simplexmlnode or dom node as loadClassMetadata should be in its own namespace and not pollute the Doctrine one. |
| Comments |
| Comment by Gediminas Morkevicius [ 27/May/11 ] |
|
Sounds logic, each driver would expect NULL or data (wrapped specifically for the driver used) |
[DDC-952] Several features to batch eager selects more efficently Created: 27/Dec/10 Updated: 04/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| 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 | ||
| Sub-Tasks: |
|
| Description |
|
This ticket aggregates several strategies to optimize batching of eager selects. |
| Comments |
| Comment by Benjamin Eberlei [ 31/Dec/10 ] |
|
Requirements for batching of eager loads: 1. Since we are using an IN() query for this we can only support this feature for entities that have a single column primary key. |
| Comment by Benjamin Eberlei [ 31/Dec/10 ] |
|
Next item to think about: What if an exception or event breaks the flow and "triggerEagerLoads()" is never called? |
[DDC-947] Optmize Code-Generation Strategies Created: 24/Dec/10 Updated: 29/Mar/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Jonathan H. Wage |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
We should optimize code-generation somehow. |
| Comments |
| Comment by Benjamin Eberlei [ 29/Mar/11 ] |
|
Descheduled to 2.x |
[DDC-896] Use PDepend for Code-Generation Created: 27/Nov/10 Updated: 27/Nov/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Tools |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Jonathan H. Wage |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Our current code-generation tool has many shortcomings and due to its hard to test nature also many (known and unknown) bugs, as well as high maintenance. Since people are overusing this tool and I am sort of annoyed by how much time goes into this we should rewrite this in a two-step procedure: 1. Move code into Common so we can share it between ORM, Mongo and CouchDB. This gives us the advantage of having to maintaining less code for this stuff. |
[DDC-1450] UnitOfWork Transaction Rollback Support Created: 24/Oct/11 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The UnitOfWork does not handle the case very well where a rollback is necessary. Can this be optimized? |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-1445] Improve error messages Created: 22/Oct/11 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Error messages throughout ClassMetadata validation and UnitOfWork cycles can be significantly improved. Work is being done on: https://github.com/doctrine/doctrine2/tree/ImproveErrorMessages |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[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-1398] loading one item at a time when indexBy and EXTRA_LAZY fetch mode is used on a collection Created: 29/Sep/11 Updated: 10/Mar/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Reio Piller | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 3 |
| Labels: | None | ||
| Description |
|
collection->get($key) Atm in 2.1.2 this is loading the entire collection. It would be really handy that it would extra lazy load only one item using the association and indexBy fields and given key value (if collection is not initialized and the key havent been loaded yet ofc) Am i making sense with this? |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
| Comment by German Caseres [ 05/Mar/12 ] |
|
Is there any fix for this? i have the same problem. |
| Comment by Oleg Namaka [ 10/Mar/12 ] |
|
It makes a perfect sense here, I wish it was possible, it would give us a room for even more optimization. Any input on the issue from the developers? |
[DDC-1393] Skipping tables or columns in database driver or SchemaTool Created: 24/Sep/11 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | 2.1.1, Git Master |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
There should be a sane way to skip sources of errors in SchemaTool and the DatabaseDriver. |
| Comments |
| Comment by Benjamin Eberlei [ 24/Sep/11 ] |
|
Idea: Develop a datastructure of sorts that allows saving information about skipping tables and columns therein when reverse engeneering. |
| Comment by Guilherme Blanco [ 09/Dec/11 ] |
|
This is not possible unless you take advantage of Topological Sorting to map class dependencies like we do inside of UnitOfWork AFTER creating the ClassMetadata. The necessity of having this is mandatory because we can never skip classes that have associations to other ones though FK. |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-1320] Ship Immutable date time with Doctrine Common, use in ORM - Should implement __toString() Created: 06/Aug/11 Updated: 31/Oct/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Comments |
| Comment by Benjamin Eberlei [ 31/Oct/11 ] |
|
Has to be pushed back as immutable date time cannot be implemented in userland that well. |
[DDC-1308] Add cache for transient information and invalidation for ClassMetadata Created: 31/Jul/11 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Mapping Drivers |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
Two different things have to be improved in the caching: 1. The information isTransient() has to be moved to the ClassMetadataFactory and cached there. |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-1543] Support for Mapping Files on Traits Created: 17/Dec/11 Updated: 17/Dec/11 |
|
| Status: | Open |
| 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 | ||
| Description |
|
With PHP 5.4 and traits coming we should find a way where you can add xml and yml configurations for a trait and upon loading an entity X, it also loads the trait configuration of this entity. |
[DDC-1530] HIDDEN values cannot be used in WhereClause Created: 12/Dec/11 Updated: 25/Jan/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | Git Master |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Guilherme Blanco | Assignee: | Guilherme Blanco |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
SELECT u, u.name AS HIDDEN n FROM User u WHERE n = ?1 Is broken. Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sclr16' in 'where clause On a query like: SELECT s0_.id AS id0, s0_.a AS a1, s0_.b AS b2, s0_.c AS c3, s0_.d AS d4, s0_.e AS e5, s0_.f AS f6, s0_.g AS g7, s0_.h AS h8, s0_.i AS i9, s0_.j AS j10, s0_.k AS k11, s0_.l AS l12, s0_.m AS m13, s0_.n AS n14, s0_.o AS o15, 123456789 AS sclr16, s0_.p AS p17 FROM myEntity s0_ WHERE s0_.a = 1 AND sclr16 <= ? ORDER BY sclr16 ASC |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
| Comment by Christian Raue [ 09/Jan/12 ] |
|
It occurs even if the value is not HIDDEN. |
| Comment by Benjamin Eberlei [ 10/Jan/12 ] |
|
@Christian this sounds like a completly different error, please explain why you think this belongs here or open a new ticket. |
| Comment by Christian Raue [ 10/Jan/12 ] |
|
Benjamin: Because I get exactly the same error message regardless of using HIDDEN. So HIDDEN doesn't seem to be liable here. |
| Comment by Benjamin Eberlei [ 10/Jan/12 ] |
|
Can you paste your DQL and SQL? |
| Comment by Christian Raue [ 10/Jan/12 ] |
|
Code: $queryBuilder
->select('myEntity, 123456789 AS distance')
->where('distance <= 10')
;
DQL: SELECT myEntity, 123456789 AS distance FROM MyCompany\MyBundle\Entity\MyEntity myEntity WHERE distance <= 10 SQL: SELECT s0_.id AS id0, s0_.a AS a1, s0_.b AS b2, s0_.c AS c3, s0_.d AS d4, s0_.e AS e5, s0_.f AS f6, s0_.g AS g7, s0_.h AS h8, s0_.i AS i9, s0_.j AS j10, s0_.k AS k11, s0_.l AS l12, s0_.m AS m13, s0_.n AS n14, s0_.o AS o15, 123456789 AS sclr16, s0_.p AS p17 FROM myEntity s0_ WHERE sclr16 <= 10 |
| Comment by Benjamin Eberlei [ 11/Jan/12 ] |
|
That is expected behavior, ANSI SQL defines SELECT to be evaluated AFTER WHERE. SELECT 1234 AS foo FROM `test` HAVING foo = 1234 DQL has a HAVING clause as well, not sure it works without the group by. Please try. |
| Comment by Christian Raue [ 21/Jan/12 ] |
|
So we might just close this issue then? |
| Comment by Benjamin Eberlei [ 25/Jan/12 ] |
|
Its not a bug, just the error message is supposed to be improved (if possible) in a cheap way. |
[DDC-1852] Doctrine\ORM\Tools\SchemaValidator should check validity of lifecycle callbacks Created: 04/Jun/12 Updated: 20/Sep/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | Git Master |
| Fix Version/s: | 2.4, 2.x, Git Master |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Marco Pivetta | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The schema validator should analyze mapped lifecycle callbacks and: a) if some lifecycle callbacks were defined, but no @HasLifecycleCallbacks annotation/mapping was set, warn the user |
| Comments |
| Comment by Marco Pivetta [ 04/Jun/12 ] |
|
Existing PR at https://github.com/doctrine/doctrine2/pull/361 |
[DDC-1729] Translate queries into graphs of value objects (instead of array hydration?) Created: 27/Mar/12 Updated: 09/Jun/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| 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 | ||
| Description |
|
In decoupled applications the model layer returns "data-transfer-objects" through the boundary into the controller/view layer. It would make sense to have Doctrine directly generate any data-transfer/value-object from native and dql queries. |
| Comments |
| Comment by Benjamin Eberlei [ 09/Jun/12 ] |
|
Example: $dql = "SELECT new CustomerAddressView(c.id, c.name, a.id, a.street, a.number, a.city, a.code)
FROM Customer c INNER JOIN c.address a WHERE c.id = ?1";
This supersedes DDC-1819. 1. One additional property in ResultSetMapping => $viewModelClass? |
[DDC-213] Persist order of collections Created: 15/Dec/09 Updated: 16/Oct/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | 2.0 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 10 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||
| Description |
|
A Collection is like a php array, an ordered map. Hence there should be the possibility to persist this order. |
| Comments |
| Comment by Christian Heinrich [ 21/May/10 ] |
|
Roman, I'd like to do this one as I have currently a use case for this. Do you have any idea of how to do this? What I'm wondering is whether it is possible to implement this without user intervention. (This would simply mean "store the entities as they were added"). But this would need another column in DB that we'd have to add within oneToMany / manyToMany relationships, but in this case one could save a serialized array holding "entityId => position" key / value pairs. Afterwards, one could easily rebuild / reorder the collection via $collection->set($entity, $order[$entity->identifier]); If you've got another thought about this, please don't hesitate to point me into the right direction! |
| Comment by Benjamin Eberlei [ 22/May/10 ] |
|
this won't be implemented until 2.1, since its a pretty complex feature. Changes are probably required in: 1. CollectionPersister - Add a new collection persister that takes the position into account You can implement this already though with some performance hit in update scenarios. If you use the ORDER BY support and implement an API around your entity that abstracts those changes and always sets a "position" field on the many entity that is supposed to be sorted. |
| Comment by Roman S. Borschel [ 22/May/10 ] |
|
I don't think we necessarily need a new collection persister. Simply adjusting the ManyToManyPersister to be able to deal with it might be sufficient. For OneToMany, that is always persisted from the "many" side, thus there is no collection persister, we would need to adjust the normal persisters. They key element for the user should be a new annotation (or corresponding xml/yaml element) @OrderColumn. By default the order should not be persistent, only when an @OrderColumn annotation is present. The name of the order column can have a default, i.e. "position". Thus this enhancement of persisting the order should be fully backwards compatible. |
| Comment by Roman S. Borschel [ 22/May/10 ] |
|
On another note, the getInsertDiff/getDeleteDiff methods of PersistentCollection should already be "ready" for this. That is, when an element in the collection changed only its position, this is already tracked as a change. However the ManyToManyPersister issues no "UPDATE" queries, it simply deletes and inserts. A position change may be more effectively persisted with an UPDATE. |
| Comment by Benjamin Eberlei [ 30/Sep/10 ] |
|
From a mailinglist entry, required check/changepoints: 1. ClassMetadata of Many-To-Many associations have to be extended to publish the required datastructure to the ORM. |
| Comment by Benjamin Eberlei [ 24/Dec/10 ] |
|
Push back to 2.x, we will have support for |
| Comment by Thomas Tourlourat - Armetiz [ 07/Feb/12 ] |
|
Hi there, Benjamin Eberlei said that : "You can implement this already", but I don't understand the "how to". Also, To get this feature without any change on Doctrine, I have remplace the PK defined by the target & mapped field identifier. The new PK is a new field with type "integer" and with auto-increment enable. It's an very bad solution, but It work before an official support. Waiting for advices, and solutions, Thomas. |
| Comment by Thomas Tourlourat - Armetiz [ 08/Feb/12 ] |
|
Answering to Benjamin Eberlei on the "7. Discuss wheather to support this for One-To-Many also with the key-column on the many side. This is much more tricky internally though.". I think that for One-To-Many relations, if user want to store the collection order, Doctrine can store the One-To-Many as Many-To-Many with a "model" limitation. What do you think about it ? |
| Comment by Nicolas [ 29/Feb/12 ] |
|
I think that it must be possible to have two keys ordering : the order isn't obligatory reversible. For exemple with user and group :
And maybe more, if you decide to add multi-order : an user show group by his rank in it, if his rank is identical, the order is make by love preference, and after by the importance given by the user (not necessary a number, if we imagine filter on them). So a default order can be choice with parametized fields and could be : @ManyToMany(targetEntity="Group") ... @JoinFields ( rank: { type: int} , preference:{type:int}, importance:{type: string, length: 40} ) @OrderByJoinFields({"rank" = "ASC", "preference"="ASC", "importance"="ASC" } ) In this case the order must be optional and would be clean if another order appears in the same scope (DQL...). And manytomany became virtual entities act as other entities except they don't appears permetting in the same time a better conception. So if the solution take in DDC-181 will become the only solution. This would a good idea to document this. Because, this seems to me a very important point. My last point is even an unique ordering field created in the join table will be a big and usefull improvement. Thank a lot for your beautiful work. |
| Comment by Thomas Tourlourat - Armetiz [ 29/Feb/12 ] |
|
In my point of view, a collection can be order in a single way only.
And it's your role to keep a consistency between members & importantMembers array. Because ManyToMany join table is the reflection of a state of an ArrayCollection. It's not a usefull feature to be able to store all of the state of an ArrayCollection, even the order of this Array. It's just a normal feature that is really missing Thomas. |
| Comment by Nicolas [ 29/Feb/12 ] |
|
I don't think: If you have three collection, you duplicate one relation 3 times and it's easy in consequence to lost the data integrity and unicity. By example :
So in my idea, the many to many relation isn't just an array collection, but should be an virtual entity. In UML or in Merise method this is a common problem to have a parametized relation. I think an orm should just implement this. |
| Comment by Thomas Tourlourat - Armetiz [ 29/Feb/12 ] |
|
Hum, |
| Comment by Thomas Tourlourat - Armetiz [ 07/Mar/12 ] |
|
I just want to add a piece of Doctrine ORM Document : "When working with collections, keep in mind that a Collection is essentially an ordered map (just like a PHP array). That is why the remove operation accepts an index/key. removeElement is a separate method that has O ( n) complexity using array_search, where n is the size of the map." |
| Comment by Thomas Tourlourat - Armetiz [ 23/Mar/12 ] |
|
Hi there, Doctrine Documentation says : "When working with collections, keep in mind that a Collection is essentially an ordered map (just like a PHP array)". But I not agree with @Nicolas. Because in his case, he's talking about Association Class : http://etutorials.org/Programming/UML/Chapter+6.+Class+Diagrams+Advanced+Concepts/Association+Class/ What do you think about it ? Thomas; |
| Comment by Thomas Tourlourat - Armetiz [ 31/Aug/12 ] |
|
Any news ? |
| Comment by Matthieu Napoli [ 16/Oct/12 ] |
|
Hi, any news on this? If I may add any info to this feature request, maybe something like JPA/Hibernate could be a good start? See http://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html or http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/collections.html#collections-indexed The idea in Hibernate is that you persist the order of the list in an extra column. This column is not a field of the entity however. |
[DDC-128] Consider adding EntityManager#link/unlink methods for direct association manipulation Created: 07/Nov/09 Updated: 29/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-ALPHA2 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
A problem when working with collection-valued associations is that almost all operations except add($obj) require the collection to become initialized in order for the operation to be performed properly. While this is all correct and beautiful OO-wise it may be problematic at times with regards to performance. Hence we might want to consider to provide some convenient methods along the lines of link/unlink (name suggestions?) which allow more direct, less OO collection manipulation. Such methods obviously would bypass the normal object lifecycle and the changes done through these methods will not be reflected in the in-memory objects and collections, unless the user keeps them in-synch himself. |
| Comments |
| Comment by Benjamin Eberlei [ 11/Dec/09 ] |
|
Questions
Regarding the naming, i like link/unlink. |
| Comment by Roman S. Borschel [ 17/Dec/09 ] |
|
What do you mean by "handled by UnitOfWork commit" ? Whether the SQL is "scheduled" or executed immediately? Interesting question. As far as usage is concerned, I currently imagine it as follows: // EntityManager#link($sourceObj, $field, $targetObj) $user = $em->getReference($userId); // $userId probably from request parameters $address = $em->getReference($addressId); // $addressId probably from request parameters $em->link($user, 'addresses', $address); "What happens if: an entity is linked with a collection, although they are already connected." Probably an SQL error which results in an exception from the driver. Depends on the database constraints though. "What happens if: an entity is unlinked from a collection it is not in" Probably nothing, at least not from the SQL side. An exception could be thrown from Doctrine itself if the update affected 0 rows. Thanks for these initial questions. Thats definitely food for thought. Keep it coming. |
| Comment by Roman S. Borschel [ 26/Aug/10 ] |
|
Pushed back. |
[DDC-54] Trigger postLoad events and callbacks after associations have been initialized Created: 15/Oct/09 Updated: 11/Oct/12 |
|
| Status: | In Progress |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-ALPHA2 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Roman S. Borschel | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 6 |
| Labels: | None | ||
| Description |
|
Currently the postLoad events and callbacks are triggered after the entity has been created and filled with its "primitive" state but before associations are available. The postLoad events and callbacks should be postponed so that they are triggered after associations have been initialized. |
| Comments |
| Comment by Roman S. Borschel [ 30/Aug/10 ] |
|
If this is to be included in 2.0 it needs to happen for RC1. However, it is not clear yet whether it will be done in time. |
| Comment by Benjamin Eberlei [ 23/Sep/10 ] |
|
How would you solve this Roman? I thought of adding a query hint so that the postLoad inside unit of work is not triggered and gathering all the entities that have a post load event in an array inside the object hydrator, then iterating it after taking the snapshots of all collections inside hydrateAll |
| Comment by Roman S. Borschel [ 24/Sep/10 ] |
|
@Benjamin: Not sure what you would use the query hint for but in general that is the approach I had in mind, yes. You can't get around iterating over the entities after the actual hydration. |
| Comment by Benjamin Eberlei [ 27/Sep/10 ] |
|
The query hint would do something like: //TODO: These should be invoked later, after hydration, because associations may not yet be loaded here. if (isset($class->lifecycleCallbacks[Events::postLoad]) && !isset($hints['hydrationPostLoad'])) { $class->invokeLifecycleCallbacks(Events::postLoad, $entity); } if ($this->evm->hasListeners(Events::postLoad) && !isset($hints['hydrationPostLoad'])) { $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em)); } another way would be to move that code out of UoW::createEntity completly and have the persisters call it when they use that method. |
| Comment by Roman S. Borschel [ 28/Sep/10 ] |
|
Leaving that code in UoW does not make sense to me, if it is moved, it needs to be moved completely. Why do you think the persisters should do it? Initially I thought collecting the affected entities during hydration and then when hydration is done iterating over them and triggering the postLoad events. |
| Comment by Benjamin Eberlei [ 28/Sep/10 ] |
|
Yes but postLoad has to be triggered for non Hydrated entities (i.e. Persister) also |
| Comment by Benjamin Eberlei [ 30/Oct/10 ] |
|
Moved back |
| Comment by Kacper Gunia [ 15/Apr/12 ] |
|
Hi Gyus, I need access to associations in postLoad or similar event, and my idea is to dispatch new event after full initialisation of object, what do You think about it? If I can help please let me know |
| Comment by Alexander Pasichnick [ 25/Sep/12 ] |
|
Now in my PostLoad access to associations is work fine. Why this issue is still in Unresolved status? |
| Comment by Łukasz Cybula [ 11/Oct/12 ] |
|
What do you (Roman and Benjamin) think about adding postHydrate event which would be called within ObjectHydrator::hydrateAllData() on every entity collected during hydration? I could prepare a patch for this. I personally think this would be better than adding a hint that changes behaviour of postLoad event. |
[DDC-298] Allow Entity to hold a collection of a single primitive type Created: 02/Feb/10 Updated: 24/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 3 |
| Labels: | None | ||
| Description |
|
Sometimes you want to save arbitrary information for an entity using a key -> value array-structure. JPA supports this by means of the @ElementCollection annotation with allows to specify HashMaps for example. I propose a new AssocationMapping called "ElementMapping" / "ElementCollection" and annotations (options): ElementCollection + elementTable + keyType + keyLength + keyColumnDefinition + valueType + valueLength + valueColumnDefinition The key and value definitions are necessary for converting and schema generation. The implementation would make use of the PersistentCollection at all times and work as any other persistent collection just with primitive types. Restrictions for a first implementation:
Use-Case: $entity->options['foo'] = 'bar'; $entity->options['bar'] = 'baz'; This could be done for 2.0 imho, adding the necessary changes and optimizations could then be scheduled for 2.1 |
| Comments |
| Comment by Benjamin Eberlei [ 02/Feb/10 ] |
|
In this implementation Schema-Tool would generate a table: elementTable (entity_id-1, ..., entity_id-n, key, value) and using the Platform Type Generation of keyType and valueType |
| Comment by Benjamin Eberlei [ 02/Feb/10 ] |
|
Column Names should be Change-able also since there could be people who name their primary keys "key" and "value" o_O |
| Comment by Benjamin Eberlei [ 02/Feb/10 ] |
|
Ordering could be implemented on top of this using the @OrderColumn JPA implementation by adding another column to the table with a numeric order that will be "order by"'d on select time. |
| Comment by Benjamin Eberlei [ 24/Dec/10 ] |
|
Pushed back |
[DDC-763] Cascade merge on associated entities can insert too many rows through "Persistence by Reachability" Created: 23/Aug/10 Updated: 04/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Dave Keen | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
I think that the UnitOfWork needs to maintain a map of spl_object_hash($newEntity)->$managedEntity for entities that were persisted via reachability during a merge. doMerge should then only call persistNew if the original entity has not already been persisted (if it has already been persisted it should merge the managed entity from the map). The map should be maintained until a flush() or until the UnitOfWork is cleared. The reasoning is as follows. Imagine we have a simple doctor object with no associations: $doctor = new Doctor();
$em->persist($doctor);
$em->persist($doctor);
$em->flush();
After the first persist() $doctor is MANAGED so the second persist has no effect and this results in a single Doctor row. If we do the same thing using merge and persistence by reachability: $doctor = new Doctor();
$em->merge($doctor);
$em->merge($doctor);
$em->flush();
we get 2 Doctor rows being added. Obviously in this particular case we should use the return value from the first merge() as the parameter of the second merge which would give correct behaviour. However, now imagine one Doctor has many Patients and many Patients have one Doctor, all the associations have cascade merge enabled, and further assume that $d1 (Doctor id=1) is already in the database. We now attempt to create two patients and assign them to the existing doctor: $d1= new Doctor(); $d1->id = 1; // This is a DETACHED entity $p1 = new Patient(); $p2 = new Patient(); $d1->patients->add($p1); $p1->doctor = $d1; $d1->patients->add($p2); $p2->doctor = $d1; $em->merge($p1); $em->merge($p2); $em->flush(); This actually results in 4 rows being added to the 'patients' table instead of 2, I think because $p1 and $p2 are getting persisted both as the root objects and then again from the patient->doctor->patients array. Since the cascade merging happens internally we can't replace the array contents with the managed return values without walking through the object graph (in which case there is no point in using cascade merge in the first place). Maintaining a map in UnitOfWork will allow doMerge to ensure it doesn't persist the same entities twice. I'm not sure, but this might be relevant for cascade persist too. P.S. Another bug report on this can be found at http://code.google.com/p/flextrine2/issues/detail?id=32 (it basically says the same thing with different entities). |
| Comments |
| Comment by Benjamin Eberlei [ 29/Aug/10 ] |
|
@Roman A possible fix for this in my opinion is another map in UnitOfWork $mergedEntities = array(); and a patch like this: diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 242d84b..1d0d8b3 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1340,6 +1340,10 @@ class UnitOfWork implements PropertyChangedListener return; // Prevent infinite recursion } + if (isset($this->mergedEntities[$oid])) { + return $this->mergedEntities[$oid]; + } + $visited[$oid] = $entity; // mark visited $class = $this->em->getClassMetadata(get_class($entity)); @@ -1468,6 +1472,8 @@ class UnitOfWork implements PropertyChangedListener $this->cascadeMerge($entity, $managedCopy, $visited); + $this->mergedEntities[$oid] = $managedCopy; + return $managedCopy; } |
| Comment by Dave Keen [ 29/Aug/10 ] |
|
I have tested this patch with my application and it fixes the problem in all my relevant test cases apart from one. The test case that's failing is one that persists a bi-directional many to many relationship, so the associations interweave with each other (if you know what I mean). I wonder if perhaps doMerge need to continue cascading even if it finds an item in $this->mergedEntities This is the Flextrine code that fails - it results in no entries in movie_artist. This might also be related to m1 = new Movie(); m2 = new Movie(); a1 = new Artist(); a2 = new Artist(); m1.artists.addItem(a1); a1.movies.addItem(m1); m2.artists.addItem(a1); a1.movies.addItem(m2); // These translate to cascade merges on the server // Now flush |
| Comment by Dave Keen [ 29/Aug/10 ] |
|
P.S. This test passes if I translate em.persist() to $em->persist() (not cascading) on the server instead of translating it to a cascade merge; not sure if that helps |
| Comment by Roman S. Borschel [ 30/Aug/10 ] |
|
I'd really like to avoid introducing an additional instance variable just to solve this issue but I did not find the time yet to really look into it. Does someone have a unit test for this already and can attach it to the issue? |
| Comment by Roman S. Borschel [ 31/Aug/10 ] |
|
Rescheduling for RC1. |
| Comment by Dave Keen [ 13/Sep/10 ] |
|
Here is a functional test case containing three tests: testMultiMerge tests basic merging of two new entities, checking that only a single entity ends up in the database. This passes with Benjamin's patch. testMultiCascadeMerge tests the more complex case of merging a OneToMany association. This also passes with Benjamin's patch. testManyToManyPersistByReachability tests the ManyToMany case described above and this fails with Benjamin's patch, probably because doMerge doesn't cascade down entities that it has already merged and some ManyToMany associations are being ignored. Its a bit hard to be certain what is causing this as even without Benjamin's patch this test would fail due to |
| Comment by Benjamin Eberlei [ 15/Sep/10 ] |
|
@Roman i thought about this issue, its not possible without that additional map of merged entities. There is no way we can get that information from other sources. Problem is rather that the use-case probably only applies in mass-merging scenarios and client-server serialization. |
| Comment by Dave Keen [ 21/Sep/10 ] |
|
Added another failing test case - adding the same entity from different ends of a many to many bi-directional association to check that there isn't an integrity constraint violation caused by Doctrine trying to add the same row twice. |
| Comment by Dave Keen [ 21/Sep/10 ] |
|
Attached a patch for this issue. |
| Comment by Benjamin Eberlei [ 22/Sep/10 ] |
|
can you comment why all the additionall stuff is necessary compared to my patch? |
| Comment by Dave Keen [ 22/Sep/10 ] |
|
It fixes the two additional test cases - testManyToManyPersistByReachability and testManyToManyDuplicatePersistByReachability. testManyToManyPersistByReachability was failing with your original patch because there are ManyToMany cases where an entity may have already been merged, but its still necessary to add it to an association and continue to cascade. Running the following with the original patch will miss out some of the associations. $m1 = new Movie(); $m1->title = "Movie 1"; $m2 = new Movie(); $m2->title = "Movie 2"; $a1 = new Artist(); $a1->name = "Artist 1"; $a2 = new Artist(); $a2->name = "Artist 2"; $m1->artists->add($a1); $a1->movies->add($m1); $m1->artists->add($a2); $a2->movies->add($m1); $m2->artists->add($a1); $a1->movies->add($m2); $m2->artists->add($a2); $a2->movies->add($m2); $em->merge($a1); $em->merge($a2); $em->flush(); The other change in my patch is to protect against this case. It ensures that the following code doesn't add the same entity twice to a collection. $em->merge($m1); $em->merge($m2); $em->merge($a2); $em->merge($a2); $em->flush(); |
| Comment by Benjamin Eberlei [ 31/Oct/10 ] |
|
I am not sure if the issue here is rather multiple calls to merge that contain different parts of the same object-graph. There should be a very simple fix for this, call ->clear() after each merge. I am not sure if this patch drags us into a blackhole of issues with merging. |
| Comment by Dave Keen [ 31/Oct/10 ] |
|
Calling ->clear() and ->flush() after each merge is a workaround for the simple case, but unless I am misunderstanding I don't think its a solution for cases where the merging is happening automatically in cascadeMerge. I've actually encountered this issue in another project and scenario to do with creating REST APIs and merging JSON objects into entities, and applying the patch fixed it so a) I think this issue might be a more common that we first thought and b) the patch basically seems to work (plus it doesn't introduce any failing cases in the existing test suite). I can actually still find one edge case to do with cascading merging interlinked many to many associations that this doesn't fix, but I was planning to open that as a new ticket after this My feeling is that the current merge already has issues and this definitely improves it. |
| Comment by Benjamin Eberlei [ 01/Nov/10 ] |
|
It cannot happen inside a single merge, single merges use the $visited to avoid infinite recursions, each entity can only be merged once inside a single merge operation. |
| Comment by Benjamin Eberlei [ 10/Nov/10 ] |
|
Added a note into the documentation about using EntityManager#clear between merging of entities which share subgraphs and cascade merge. Handling this issue in UnitOfwork will be declared an improvement, not a bug anymore and be scheduled for later releases. The required changes to the core are to dangerous and big. |
| Comment by Dave Keen [ 11/Nov/10 ] |
|
Where in the docs is that? Just to summarize, the equivalent operation to having multiple merges and a single flush is to call merge followed by flush each time, with the whole thing surrounded by a transaction? Does this have a big impact on performance? |
| Comment by Dave Keen [ 11/Nov/10 ] |
|
Ben - even given the decision not to implement this (and I do understand your thinking, as it is a major change), is there any reason not to implement the bit that ensures that the same entity isn't added to a collection twice during a merge? I can't think of a situation where this should be allowed, and I have a use case where I get 'DUPLICATE KEY' errors if this isn't there. Please see attached patch. |
| Comment by Benjamin Eberlei [ 11/Nov/10 ] |
|
What bit of that huge patch is that? Can you extract it into another ticket if thats possible? |
| Comment by Benjamin Eberlei [ 11/Nov/10 ] |
|
I added it to "Working with Objects" and the descripton of Merge. Its not yet live on the site. Using this current workaround has a performance impact, since more SELECT statements have to be issued against the database. |
| Comment by Dave Keen [ 11/Nov/10 ] |
|
Apologies for not being clear - only the 3rd patch (multipleaddmerge.diff) is relevant to the 'DUPLICATE KEY' error I am now talking about, but I'll put it in a nother ticket if you prefer. |
| Comment by Benjamin Eberlei [ 11/Nov/10 ] |
|
please add a new ticket, patch looks good. |
| Comment by Dave Keen [ 11/Nov/10 ] |
|
Created as |
[DDC-717] Do not use files when using proxy autogeneration Created: 22/Jul/10 Updated: 04/Jul/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Jaka Jancar | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Description |
|
Proxy classes are generated in less than 1ms for me. I prefer to not have a "build" step to reducing loading time by a milisecond, so I use autogenerate. For users like me, wouldn't it be nicer if we wouldn't even have to configure a proxy dir and those files were never written (since they're not read more than once anyway)? |
| Comments |
| Comment by Jaka Jancar [ 22/Jul/10 ] |
|
This very minimal patch removes the use of these temporary files: --- library/Doctrine/ORM/Proxy/ProxyFactory.php (revision 2)
+++ library/Doctrine/ORM/Proxy/ProxyFactory.php (working copy)
@@ -78,9 +78,8 @@
$fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
if ($this->_autoGenerate && ! class_exists($fqn, false)) {
- $fileName = $this->_proxyDir . DIRECTORY_SEPARATOR . $proxyClassName . '.php';
- $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, $fileName, self::$_proxyClassTemplate);
- require $fileName;
+ $file = $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, null, self::$_proxyClassTemplate);
+ eval('?>'.$file);
}
if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) {
@@ -144,6 +143,9 @@
$file = str_replace($placeholders, $replacements, $file);
+ if ($fileName === null)
+ return $file;
+
file_put_contents($fileName, $file);
}
|
| Comment by Benjamin Eberlei [ 23/Jul/10 ] |
|
The proxy dir is used for the "doctrine orm:generate-proxies" command in the case of "autogenerate= false", so you need to define it anyways. You have to use proxies, the option is not for Proxy yes/no. If you have autogenerate=false and doctrine requires a proxy for a use case but can't find it you will get a fatal error. |
| Comment by Benjamin Eberlei [ 23/Jul/10 ] |
|
I just saw the eval() keyword, ieeks |
| Comment by Jaka Jancar [ 23/Jul/10 ] |
|
eval() is no different than writing code to a file and using require(). When using runtime-generated proxies, there are no benefits (that I know of) from writing them to a file. The disadvantages are:
This is a nicer patch, which makes _generateProxyClass() return a string, just like other _generate* methods: --- library/Doctrine/ORM/Proxy/ProxyFactory.php (revision 2)
+++ library/Doctrine/ORM/Proxy/ProxyFactory.php (working copy)
@@ -78,9 +78,8 @@
$fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
if ($this->_autoGenerate && ! class_exists($fqn, false)) {
- $fileName = $this->_proxyDir . DIRECTORY_SEPARATOR . $proxyClassName . '.php';
- $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, $fileName, self::$_proxyClassTemplate);
- require $fileName;
+ $code = $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName);
+ eval($code);
}
if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) {
@@ -107,19 +106,19 @@
foreach ($classes as $class) {
$proxyClassName = str_replace('\\', '', $class->name) . 'Proxy';
$proxyFileName = $proxyDir . $proxyClassName . '.php';
- $this->_generateProxyClass($class, $proxyClassName, $proxyFileName, self::$_proxyClassTemplate);
+ $code = $this->_generateProxyClass($class, $proxyClassName);
+ file_put_contents($proxyFileName, "<?php\n" . $code);
}
}
/**
* Generates a proxy class file.
*
- * @param $class
- * @param $originalClassName
+ * @param ClassMetadata $class
* @param $proxyClassName
- * @param $file The path of the file to write to.
+ * @return string The code of the generated methods.
*/
- private function _generateProxyClass($class, $proxyClassName, $fileName, $file)
+ private function _generateProxyClass(ClassMetadata $class, $proxyClassName)
{
$methods = $this->_generateMethods($class);
$sleepImpl = $this->_generateSleep($class);
@@ -142,9 +141,9 @@
$methods, $sleepImpl
);
- $file = str_replace($placeholders, $replacements, $file);
+ $file = str_replace($placeholders, $replacements, self::$_proxyClassTemplate);
- file_put_contents($fileName, $file);
+ return $file;
}
/**
@@ -244,8 +243,7 @@
/** Proxy class code template */
private static $_proxyClassTemplate =
-'<?php
-
+'
namespace <namespace>;
/**
|
| Comment by Benjamin Eberlei [ 24/Jul/10 ] |
|
Scheduled usage of eval() for 2.1, if the following conditions exist: 1. Autogenerate is set to TRUE |
| Comment by Jaka Jancar [ 24/Jul/10 ] |
|
Great, this is even better. This way you can have 1) autogenerated in ram-only, 2) autogenerated in files and 3) pregenerated. And the minimal amount of config needed to get up and running is reduced, which is always nice. |
| Comment by Benjamin Eberlei [ 24/Jul/10 ] |
|
you should know though, eval is dead slow. It generates the necessary proxies on EACH request and that cannot be cached in APC. |
| Comment by Jaka Jancar [ 24/Jul/10 ] |
|
It's no slower than current autogeneration (file_put_contents+require). TBH, I don't know why anyone would want to use that over eval(), but I don't mind it being there. Pre-generation is, of course, a different thing. Seems like a valid tradeoff to offer: build/a bit of config/better perfomance vs. no build/no config/potentially slower. |
| Comment by Benjamin Eberlei [ 24/Jul/10 ] |
|
Yes, that is because file_put_contents + require is a development only strategy. The manual clearly states that autogenerate has to be false in production. |
| Comment by Roman S. Borschel [ 12/Aug/10 ] |
|
Using eval() instead of producing and requiring the file in the case of enabled auto-generation of proxy classes sounds like a good improvement for 2.1 to make proxies more transparent during deveopment and for anyone for whom performance is no issue. I'm increasing the priority as I think it is easy to implement for 2.1 and a good enhancement. |
| Comment by Karsten Dambekalns [ 09/Feb/11 ] |
|
A note on why having the proxies written to a file can be useful even with autogenerate being on: it makes it really easy to check the proxy code being generated. I use that a lot currently. The solution suggested, giving three possibilities is cool, though. |
[DDC-676] Find a way to test serialize/unserialize of all ClassMetadata properties in isolation Created: 10/Jul/10 Updated: 29/Aug/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
We should find a way, using PHPUnit Data Providers or anything else, to check the serialize/unserialize of every property in the ClassMetadata instance, since errors here can be very subtle but dangerous. |
[DDC-667] Lock Timeout Query Hint for DQL Queries Created: 04/Jul/10 Updated: 16/Sep/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-BETA2 |
| 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 | ||
| Description |
|
After the implementation of This will be a DQL query feature only and be available via a query hint: $query->setHint(Query::LOCK_TIMEOUT, $timeoutMs); It will be only working on Oracle. |
| Comments |
| Comment by Roman S. Borschel [ 30/Aug/10 ] |
|
If this is to be implemented for 2.0, it needs to happen for RC1, therefore rescheduling to RC1. Feel free to reschedule to 2.x if necessary. |
| Comment by Benjamin Eberlei [ 16/Sep/10 ] |
|
Only oracle supports lock timeouts and no other vendor seems to plan to support it. I move to 2.x, but i guess this would rather be an issue of user extension. |
Allow @Id on @ManyToOne fields
(DDC-117)
|
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Sub-task | Priority: | Major |
| Reporter: | Mickael Perraud | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Environment: |
Ubuntu 10.04 + Oracle 11g Entreprise + PHP 5.3.2 + Doctrine2 Git (up-to-date) |
||
| Description |
|
I am playing with reverse engineering with Oracle and I have some problems: My schema: drop table PHONE_NUMBER; drop table CUSTOMER; create table CUSTOMER ( CUSTOMER_ID NUMBER(4) not null, CUSTOMER_LASTNAME VARCHAR2(50) not null, CUSTOMER_MODIFIED DATE, constraint PK_CUSTOMER primary key (CUSTOMER_ID) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; create table PHONE_NUMBER ( PHONE_NUMBER_ID NUMBER(4) not null, CUSTOMER_ID NUMBER(4) not null, PHONE_NUMBER VARCHAR2(50) not null, PHONE_NUMBERMODIFIED DATE, constraint PK_PHONE_NUMBER primary key (PHONE_NUMBER_ID, CUSTOMER_ID) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; alter table PHONE_NUMBER add constraint PHONE_NUMBER__CUSTOMER foreign key (CUSTOMER_ID) references CUSTOMER (CUSTOMER_ID); I obtain "Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'Property "customerId" in "PhoneNumber" was already declared, but it must be declared only once'" It's because a foreign key is a component of the primary key. |
| Comments |
| Comment by Mickael Perraud [ 28/Jun/10 ] |
|
This is the continuation of http://www.doctrine-project.org/jira/browse/DDC-616. Only the schema is different. |
| Comment by Benjamin Eberlei [ 28/Jun/10 ] |
|
just for understanding this scenario: Is this a One-To-One relation and the TABLE_TEST2 "inherits" the primary key from its parent TABLE_TEST1? If yes, this construct is not yet supported by Doctrine 2, we still need to include an ID-Generator that supports this kind of schema. |
| Comment by Mickael Perraud [ 28/Jun/10 ] |
|
Change for a more understandable use case. Note that it's not my real use case and that I work on legacy database on which I can't change the structure. |
| Comment by Benjamin Eberlei [ 01/Jan/11 ] |
|
updated the issue topic to get a better grasp of what needs to be done here. |
| Comment by waldo [ 09/Jun/11 ] |
|
I have the same error with Mysql whit the same condition. |
| Comment by Benjamin Eberlei [ 28/Nov/11 ] |
|
More details on the work to be done: The relevant code is in Doctrine/ORM/Mapping/Driver/DatabaseDriver.php only. The idea is currently many-to-many tables are detected by checking that the table has foreign keys on all the primary key columns (no additional columns!) Now with the 2.1 feature of foreign key/primary key entities this is not necessarily true anymore. You can have the primary keys being foreign keys BUT have additional columns that are not part of the primary key. This has to be detected. If a foreign key-primary-key entity is found that has additional columns a ClassMetadata has to be created and the associations have to be created with the "id" => true flag in mapManyToOne(). |
| Comment by Scott Steffens [ 11/Dec/11 ] |
|
For what it's worth, I'm getting this error when I have a PK that is a single column and not a FK. PRIMARY KEY (`id`), |
[DDC-624] Partial object query that leaves out an association to avoid loading it fetches the association anyway. Created: 03/Jun/10 Updated: 11/Nov/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | 2.0-BETA1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
Assuming: Customer <onetoone> Cart where Cart is the owning side. Since the association from Customer to Cart can not be lazy, it would make sense to leave out the association in a query to avoid loading the carts like this: select partial c.{id,name, ... anything except cart} from Customer c"
But this is ignored and the carts of all customers are fetched anyway. Query::HINT_FORCE_PARTIAL_LOAD is an alternative solution, however it has the disadvantage that it disables lazy-loading for all queried objects. If partial querying would honor associations this would allow more fine-grained control. |
| Comments |
| Comment by Roman S. Borschel [ 26/Aug/10 ] |
|
Might need to be pushed back to a 2.0.x / 2.x.x bugfix release. Not clear yet. |
[DDC-668] add upsert support Created: 04/Jul/10 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Lukas Kahwe | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 4 |
| Labels: | None | ||
| Description |
|
Didnt find anything in the docs on this. Is D2 capable of doing an UPSERT [1] in case I am trying to persist an object that may or may not have been saved previously. Different RDBMS support different syntax for this case. Like MySQL has INSERT .. ON DUPLICATE KEY UPDATE (or even INSERT IGNORE) while the SQL standard defines a MERGE syntax which seems to be gaining support. Of course you can always fallback to a SELECT FOR UPDATE (or if you want to be hacky an INSERT which catches duplicate key violations .. but probably not a good idea since many RDBMS rollback on a failure inside a transaction). [1] http://en.wikipedia.org/wiki/Upsert See also http://opensource.atlassian.com/projects/hibernate/browse/HHH-3011 asking for MERGE support Ideally there would be a way to define on a model or model instance level if merge logic should be applied. |
| Comments |
| Comment by Robert Burkhead [ 09/Jul/10 ] |
|
Doctrine_Record defines a replace() method. In the MySQL Doctrine implementation, however, it is not the same as INSERT .. ON DUPLICATE KEY UPDATE. The replace() method implemented in Doctrine_Connection_Mysql uses the REPLACE INTO syntax, which is a DELETE and then INSERT when the key exists. This is fine, except for tables that use auto-increment fields. The delete-then-insert operation yields a new auto-incremented value, whereas INSERT .. ON DUPLICTATE KEY UPDATE would not. |
| Comment by Lukas Kahwe [ 09/Jul/10 ] |
|
MySQL (and SQLite) REPLACE is a no go. It causes way too much disc I/O and worse yet totally screws up the on disk data structures because of the deleting. |
| Comment by Benjamin Eberlei [ 31/Jul/11 ] |
|
Scheduled for 2.2 |
| Comment by Benjamin Eberlei [ 31/Jul/11 ] |
|
Evaluating this makes me sad, except MySQL support for this is rather non-existant, and the oracle merge is aiming at batch operations. |
| Comment by Benjamin Eberlei [ 22/Oct/11 ] |
|
Should this be done with 1. Select first, then insert I am leaning towards 1. |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-93] It would be nice if we could have support for ValueObjects Created: 01/Nov/09 Updated: 14/Apr/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Avi Block | Assignee: | Guilherme Blanco |
| Resolution: | Unresolved | Votes: | 37 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||
| Description |
| Comments |
| Comment by Benjamin Eberlei [ 05/Nov/09 ] |
|
formated snippets nicely |
| Comment by Andrea Turso [ 09/Dec/09 ] |
|
I need this feature too. But I would suggest using the same annotation used by JPA @Embeddable +1 |
| Comment by Alan Gabriel Bem [ 17/Dec/09 ] |
|
You should also take into consideration different storage strategies of ValueObjects. Martin Fowler points out - in „PoEAA" - two approaches: Embedded Value (which is the one presented above) and Serialized LOB . |
| Comment by Avi Block [ 17/Dec/09 ] |
|
Of course technically we can similate a serialized LOB with a new Doctrine 2 type. |
| Comment by Alan Gabriel Bem [ 17/Dec/09 ] |
|
I don't like that idea - Its so not generic. VO as a pattern is important building block of domain model, which clearly indicates that VO as a feature of Doctrine2 should be tailor-made. To anyone of dev-team reading this issue: without VOs Doctrine is not yet DDD-ready, please hurry |
| Comment by Roman S. Borschel [ 18/Dec/09 ] |
|
Serialized LOB is not very useful IMHO and has lots of problems (many mentioned in PoEEA already). @Alan: I appreciate your nice reminder and I'm sure you mean it in a friendly way, but please keep in mind that noone is paid to work on this project. It all happens in free/spare time and the current state of the project already consumed at least 1 1/2 years spending many hours weekly on this project from me alone. Not to speak of the others. Thus, there is no point in demanding something or telling us to hurry. The best way to get a feature in is to provide a (good) patch that we find worth including. I started to add notes to this issue to collect all the things that need to be done for this feature. In the meantime, its not too hard/ugly to get a half-way decent embedded value yourself: /** @Entity @HasLifecycleCallbacks */
class Foo {
// annotations not shown
private $id;
private $embedded;
private $value1; // never reveal to public
private $value2; // never reveal to public
private $value3; // never reveal to public
public function getEmbedded() {
return $this->embedded;
}
public function setEmbedded($embedded) {
$this->embedded = $embedded;
}
/** @PrePersist @PreUpdate */
function _destructEmbedded() {
// destruct $embedded into $value1, $value2, $value3
}
/** @PostLoad */
function _constructEmbedded() {
// construct $embedded from $value1, $value2, $value3
}
}
Several variations of this are possible, also with an external event listener instead of callbacks but in that case you might need to use reflection to get at the values. |
| Comment by Alan Gabriel Bem [ 25/Dec/09 ] |
|
I want to share my thoughts on possible VOs collections implementations. 1. As it was mentioned earlier serialized (C)LOB is one solution. Implementation of storing/retrieving object graphs alone is quite simple, but it's complex in terms of SELECTs with conditions. I'm not taking Regexp or XPath operators into consideration as only few RDBMS support them. 2. The second solution is to break VOs graph into separate related table... or tables if we consider that VO can contain another VO(s). It's not so fast as serialized LOB but more flexible and it utilize power of RDMS, In conclusion: I can't tell which approach is superior, because each of them is valid under different circumstances. Hope this helps. @Alan: I appreciate your nice reminder and I'm sure you mean it in a friendly way [...] Of course I do. |
| Comment by Benjamin Eberlei [ 13/Mar/10 ] |
|
It would be easy to implement value objects in userland using the XML capabilities of many RDBMS: 1. Implement an Xpath function on the Dql Parser The second point can be heavily optimized when value objects are immutable with an own identiy map of value types inside the Type flyweight instance. |
| Comment by Avi Block [ 13/Mar/10 ] |
|
I more or less suggested something similar above. |
| Comment by Benjamin Eberlei [ 14/Mar/10 ] |
|
ah, my bad - i must have overseen this |
| Comment by John Kleijn [ 16/May/10 ] |
|
+1 This would be awesome. |
| Comment by Matthias Pigulla [ 09/Nov/10 ] |
|
Don't forget (especially with regard to SLOBs) that values might in turn contain references to Entities. Example: An "Order" might be an @Entity and might have a field (an array) of OrderLineItems as value. Each OrderLineItem might e. g. carry quantity or disconunt and references a Product (@Entity). So even if you don't need the traversal from Product to all the Orders it is contained in, serializing the OrderLineItems needs a way to "cut off" the object graph at the transition towards the Product but must place some kind of referral there so that upon unserialization (of the OrderLineItem list, that is, during Order load) the Product references in every OrderLineItem are at least initialized with proxies again. Don't know whether/how referential integrity (OrderLineItems <-> Products) would make sense or could be implemented here. |
| Comment by Benjamin Eberlei [ 24/Dec/10 ] |
|
Pushed back to 2.x, this feature is probably the largest feature request we have and we'd rather focus on small improvements for 2.1 |
| Comment by Nino Martincevic [ 11/Jan/11 ] |
|
Several thinks to consider/not to oversee here: 1) There are value objects with identity. I know that is not DDD-conform but only at first sight. It means they are technically entities but are treated like VOs. 2) In virtually all (business) cases a collection of VO is an Entity. How else could you reference (add or remove) single elements of that list? @Matthias: OrderLineItems is an example of actually being an Entity. |
| Comment by Ondrej Sibrina [ 03/Jun/11 ] |
|
Hi guys. I face this in my own way. Hope you won't wake up your neighbours with loud laugh. Every @Entity extends my BaseEntity object which provide kind of wrap for value with ValueBase object. So when want to get/set value from entity you call $entity->getData() where you won't get value "data" but wrapping ValueBase for value "data". Then you can get bare value by getValue(). Name of value class is in annotation and would be child of ValueBase. There's also parent class Base for EntityBase and ValueBase. In my case class Base is something like HTML element. So in the end you can use $entity->renderHtml() or $value->renderHtml() no matter if you're rendering value or @Entity. There's more features like validation, filtering and hydration value/entity from HTML forms, but it's extra. Implementation: "Base.php"
/* @MappedSuperclass */
abstract class Base {
/* there're methods like _getParent(), _getPropertyName(), etc. used in code behind */
}
"ValueBase.php" abstract class ValueBase extends Base { public function getValue() { return $this->_getParent()->{$this->_getPropertyName()}; } public function setValue($value) { $this->_getParent()->{$this->_getPropertyName()} = $value; } } "EntityBase.php" /** @MappedSuperclass */ abstract class EntityBase extends Base { public function __call($name, $arguments) { /* get property object */ $pattern = '/^get(.*)$/u'; preg_match($pattern, $name, $matches); if (isset($matches[1])) { $propertyName = lcfirst($matches[1]); return $this->get($propertyName); } /* set entity */ $pattern = '/^set(.*)$/u'; preg_match($pattern, $name, $matches); if (isset($matches[1])) { $propertyName = lcfirst($matches[1]); return $this->set($propertyName, $arguments[0]); } } public function get($propertyName) { $property = $this->_getElementProperty($propertyName); if ($property == null) throw new Exception(sprintf("There isn't property like '%s'.", $propertyName)); /* for collections and entities */ if ($property["type"] == "collection" || $property["type"] == "entity") { $element = $this->{$propertyName}; if ($element != null) { $element->_setParent($this); $element->_setPropertyName($propertyName); } elseif ($property["type"] == "entity") { $element = new $property["class"]; $element->_setParent($this); $element->_setPropertyName($propertyName); $element->_setNullEntity(); $this->{$propertyName} = $element; } return $element; } else { /* for values */ if (!isset($this->_loadedEntities[$propertyName])) { $this->_loadedEntities[$propertyName] = new $property["class"]($this, $propertyName); } return $this->_loadedEntities[$propertyName]; } } public function set($propertyName, $value) { $property = $this->_getElementProperty($propertyName); if ($property == null) throw new Exception(sprintf("There isn't property like '%s'.", $propertyName)); /* for collections and entities */ if ($property["type"] == "collection" || $property["type"] == "entity") { $this->{$propertyName} = $value; } /* for values */ else { throw new Exception(sprintf("Can't call set on value property '%s'.", $propertyName)); } return $this; } } Note that there's something i call "NullEntity". Instead of getting bare "null" you'll get @Entity child of EntityBase, where is set property nullEntity. Then there's posibility to work with null entity (for example renderHtml with empty inputs). It would be nice, if this is support by Doctrine natively, because i have some performace problems with my implementation. If it's interest in my whole code i can send you. But of course there's some security holes so i'll send it privetely. Thanks for understand and for Doctrine of course. |
| Comment by Mathias Verraes [ 13/Jul/11 ] |
|
Note that Roman's workaround presented here does not work. /** @PrePersist @PreUpdate */
function _destructEmbedded() {
// destruct $embedded into $value1, $value2, $value3
}
Doctrine tracks changes and does not perform updates when no changes are found. $embedded is not mapped, so it's not tracked and won't be taken into account by Doctrine when updating. Therefore, if $embedded is the only value that was changed, the PreUpdate event won't be triggered. The easiest thing to do is to simply destruct the VO on every mutation: public function setEmbedded($embedded) { $this->embedded = $embedded; $this->_destructEmbedded(); } The downside is that you need to remember to call the method in every setter, but apart from that, there are no side effects, it always works and it's just one line of code _constructEmbedded() keeps working as is, postLoad will always be triggered. |
| Comment by Benjamin Dulau [ 18/Dec/11 ] |
|
Hi, This feature would be awesome ! If you plan to implement this, please remember that you can have nested VOs. I have no doubts that you've already took this in consideration, but i prefer pointing this out, just in case |
| Comment by Benjamin Eberlei [ 20/Jan/12 ] |
|
work has been started, https://github.com/doctrine/doctrine2/pull/265 |
| Comment by Matthias Pigulla [ 23/Nov/12 ] |
|
Does the new "complex sql types" feature help here - I mean, could that be used to map a value object to more than one column in the database? |
| Comment by songoko songowan [ 10/Feb/13 ] |
|
@Benjamin Eberlei The request seems to be closed in the link you provided! Does that mean that this feature won't be implemented?! |
| Comment by Marco Pivetta [ 10/Feb/13 ] |
|
songoko songowan no, it just probably wasn't the correct way of implementing this |
| Comment by Daniel Pitts [ 11/Apr/13 ] |
|
I'm curious if any effort is currently being put into this. I would really love to have this feature available. |
| Comment by Marco Pivetta [ 11/Apr/13 ] |
|
Daniel Pitts this is being developed in DDC-2374 ( https://github.com/doctrine/doctrine2/pull/634 ) |
[DDC-1216] A way to mark an entity to always use result cache. Like @UseResultCache class annotation. Created: 19/Jun/11 Updated: 06/Apr/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.x |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | Reio Piller | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Description |
|
So that even associations, find(), findBy() etc will be affected. Very useful for entities that are being used on every request. Is that thinkable? |
| Comments |
| Comment by Menno Holtkamp [ 06/Apr/12 ] |
|
During development, I tried to have the out-of-the-box ORM layer handle as much of the queries as possible, essentially I used the Repository functions a lot: For example, having a specific Repository extend the Doctrine EntityRepository and do something like:
public function findByName($name)
{
$criteria = array('_name' => $name);
return parent::findBy($criteria);
}
Now all functionality is developed, I am optimizing performance and I find myself having to refer my Repository to my DAO layer which uses DQL, so I can enable the DQL Result Cache...
public function findByName($name)
{
//Use the DAO so we can enable DQL ResultSet caching
return $this->_getDao()->loadByName($name);
}
It would be nice to be able to configure 'DQL Result Cache = on' on Repository level as well... |
[DDC-838] SchemaTool - ignores the attribute uniq in relations Created: 13/Oct/10 Updated: 29/Oct/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Tools |
| Affects Version/s: | 2.0-BETA4 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | gektor | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Ubuntu, PHP 5.3.2, MySQL |
||
| Description |
|
Mapper <entity name="Default_Model_Test" table="test"> <id name="id" type="integer" column="id"> <generator strategy="AUTO"/> </id> <field name="blabla" column="blabla" type="boolean"/> <one-to-one field="user" target-entity="Users_Model_User"> <join-column name="users_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" unique="false" /> </one-to-one> </entity> SQL CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, users_id INT DEFAULT NULL, blabla TINYINT(1) NOT NULL, UNIQUE INDEX test_users_id_uniq (users_id), PRIMARY KEY(id)) ENGINE = InnoDB; ALTER TABLE test ADD FOREIGN KEY (users_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE; Actual: Expected: |
| Comments |
| Comment by Benjamin Eberlei [ 14/Oct/10 ] |
|
Verified, i just don't understand why you are using a one-to-one relation and then "deactivate" the database constraint for this. You could easily use Many-To-One |
| Comment by gektor [ 14/Oct/10 ] |
|
You are right. It's not a bug, it's feature. |
| Comment by Benjamin Eberlei [ 29/Oct/10 ] |
|
This might still be a good improvement to allow the flexibility, but its not a bug. Updating to "Minor Improvmenet for 2.x" |
[DDC-1373] Map file with specific class Created: 13/Sep/11 Updated: 14/Feb/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Mapping Drivers |
| Affects Version/s: | 2.1.1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | Thomas Tourlourat - Armetiz | Assignee: | Fabio B. Silva |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Debian LAMP - PHP5.3 - Apache 2 |
||
| Description |
|
Hi there, It's a cool feature because it's allow loading on-demand. It should be great to be able to manually map XML/YAML File description to a Class, like : This feature is simple to implement, just add a new array inside AbsractFileDriver to know the mapping. AbsractFileDriver->getAllClassNames () just return value of mapping array. With this new feature, it allow developers to create a pretty folder that contains entities mapping. Armetiz. |
| Comments |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-1370] preInsert, postInsert, prePersist, postPersist, preUpdate, postUpdate code and documentation of events Created: 09/Sep/11 Updated: 20/Dec/11 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | Guilherme Blanco | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Description |
|
Currently we have a set of Lifecycle events, but they seem to be misleading both in actual implementation and documentation. One good example is prePersist and postPersist, which is only fired when you're creating new entities. It should be renamed to preInsert and postInsert. But if we rename prePersist and postPersist to (pre|post)Insert, we may have a situation where you wanna cover both insert and update. |
| Comments |
| Comment by Rafael Dohms [ 09/Sep/11 ] |
|
Also, documentation for post* methods is broken at the website: "Changes in here are not relevant to the persistence in the database, but you can use this events to" It cuts off in mid-sentence. |
| Comment by Guilherme Blanco [ 09/Dec/11 ] |
|
RDohms, this paragraph was already sorted out. The actual ticket is still valid here. |
| Comment by Guilherme Blanco [ 20/Dec/11 ] |
|
Updating fix version |
[DDC-17] Ability to skip the operation from a pre-operation event handler Created: 20/Sep/09 Updated: 26/Aug/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Minor |
| Reporter: | Ismo Toijala | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
In Doctrine 1.1 it is possible to skip the operation in the event handlers in Doctrine_Record_Listener using Doctrine_Event::skipOperation. This no longer seems to be possible in Doctrine 2.0 Alpha 1, for example when handling a preRemove event to implement soft-delete behaviour. Perhaps a method could be added to \Doctrine\Common\EventArgs\LifecycleEventArgs to skip the operation, at least before the operation. Without this implementing soft-delete would require the user to update deleted_at and deleted_by himself and then save the record. It could no longer be done automatically when removing a record because the record is then removed. |
| Comments |
| Comment by Roman S. Borschel [ 20/Sep/09 ] |
|
The problem is, full support for soft-delete throughout the system is not feasible and very fragile. Simple soft-delete through skipping the delete operation is the easiest part. Then you will probably want to modify all DQL queries so that they adhere to it automatically and then there will always be still queries that do NOT go through DQL, like even internal lazy-load queries or native queries or others, which would need to be modified also. To sum it up, implementing soft-delete "inside" doctrine is absolutely not worth the effort and imho a bad idea and I'm certainly not willing to make lots of adjustments to the core that have a negative impact on performance just to make this soft-delete possible. I really recommend handling "soft" deletes yourself, the normal way, by simply abstracting entity retrieval and persistence through a DAO/repository layer. As a nice side-effect you get less magic and it still works when you swap out doctrine for another persistence provider. I am willing to add support for skipping deletes and maybe some other operations through events but I'm not willing to go any further, as explained above. |
[DDC-547] Consider allowing custom PersistentCollection implementations Created: 27/Apr/10 Updated: 24/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-BETA1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Minor |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 6 |
| Labels: | None | ||
| Description |
|
We should consider allowing the configuration of custom PersistentCollection implementations on a per-association basis. For this, PersistentCollection needs to be designed for inheritance. |
| Comments |
| Comment by Roman S. Borschel [ 26/Aug/10 ] |
|
Rescheduled for 2.1. Might be 2.x. |
| Comment by Benjamin Eberlei [ 24/Dec/10 ] |
|
Reschedule for 2.x |
[DDC-445] Evaluate possible ways in which stored procedures can be used Created: 19/Mar/10 Updated: 24/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
We should evaluate the current situation of stored procedure support as well as where we want to go with it / how far we want to support it, if at all. |
| Comments |
| Comment by Benjamin Eberlei [ 19/Mar/10 ] |
|
I think this relates to the usage of Custom Persisters |
[DDC-391] Allow to specifiy custom Entity and Collection Persister classes Created: 06/Mar/10 Updated: 24/Sep/12 |
|
| Status: | In Progress |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.0-ALPHA4 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | New Feature | Priority: | Minor |
| Reporter: | Benjamin Eberlei | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 5 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||
| Description |
|
It should be allowed to overwrite the default persisters for collections and entities. This should go along the lines of Hibernate which allows to set the custom implementations like: XML: <entity persister="persisterClass" /> <OneToMany persister="persisterClass" /> Annotation /** * @Entity(persister="persisterClass") * @OneToMany(persister="persisterClass") */ |
| Comments |
| Comment by Roman S. Borschel [ 19/May/10 ] |
|
Rescheduling for beta3. |
| Comment by Roman S. Borschel [ 07/Jul/10 ] |
|
Pushing back to beta4. |
| Comment by Roman S. Borschel [ 12/Jul/10 ] |
|
Moved to 2.1 due to lack of time for any larger new features for 2.0. |
| Comment by Benjamin Eberlei [ 13/Oct/10 ] |
|
implemented this in a feature branch for now, it really doesnt touch any other runtime code so maybe we can still merge this before RC1 http://github.com/doctrine/doctrine2/tree/OverridePersisters |
| Comment by Gediminas Morkevicius [ 25/Feb/11 ] |
|
Is this forgotten? you should merge it since it does not affect any other parts of ORM, this is a great feature |
| Comment by Benjamin Eberlei [ 26/Feb/11 ] |
|
This has not been forgotten, but the Persister is due for a heavy refactoring for 2.2 probably, when we will make it use the SQL Query object that we are working on. So I cannot merge this, because the API will probably break big time. |
| Comment by Jonas Wouters [ 16/Mar/11 ] |
|
Does that mean we will not see this feature before 2.2? |
| Comment by Benjamin Eberlei [ 16/Mar/11 ] |
|
Yes, that is correct. I dont want to add it as experimental/undocumented feature because people will take it for granted and make us responsible for possible bc breaks. I will update the target version accordingly. Sorry for disappointing you, but this feature is fundamentally important at the core of the library. That means we have to get it right and not rush into it. |
| Comment by Gediminas Morkevicius [ 17/Mar/11 ] |
|
Just as I thought that first you will want to make a query builder object for all persisters. since now they use plain sql. Thanks for all your work on this |
| Comment by Adam Brodziak [ 11/Jan/12 ] |
|
I might be mistaken, but AFAICS mentioned Persister heavy refactoring did not made through to 2.2 version. Is there any plan to have it in 2.3 or at any later stage? |
| Comment by Guilherme Blanco [ 13/Jan/12 ] |
|
@Adam I refactored all Persisters optimizing their code, but I could not complete the move from SQL string generation to Doctrine\DBAL\Query. |
| Comment by Thomas Rothe [ 05/Sep/12 ] |
|
Why is it still missing in 2.3? I would require this for an extension that uses its own overridden entity persister and using a custom persister is the solution that you guys recomend for not overriding the entity manager. |
| Comment by sebastiaan stok [ 23/Sep/12 ] |
|
Any change seeing this soon? I really need this for a security feature. What is making this so hard? just adding an setEntityPersister($entityName, $object) should do the trick. Edit: OK, I'm shot I CAN NOT overwrite the entity manager as the UnitOfWork is private! |
| Comment by Stefan Kögel [ 24/Sep/12 ] |
|
Any chance you could add this quickly? I need this feature urgently to complete an extension using a custom persister. Thanks in advance. |
[DDC-4] Implement support for Concrete Table Inheritance Created: 09/Sep/09 Updated: 24/Dec/10 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.1 |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
A first implementation could probably live without support for polymorphic queries (requires SQL UNIONs to be generated). |
Add the notion of read-only entities
(DDC-209)
|
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL, ORM |
| Affects Version/s: | None |
| Fix Version/s: | 2.x |
| Security Level: | All |
| Type: | Sub-task | Priority: | Minor |
| Reporter: | Roman S. Borschel | Assignee: | Roman S. Borschel |
| Resolution: | Unresolved | Votes: | 5 |
| Labels: | None | ||
| Description |
|
Setting such a query hint to TRUE should result in all entities being retrieved by that query to be read-only for the purposes of change-tracking. Note that the entities themselves need not necessarily be read-only in general. This feature is a flush performance tweak that can be used to query for objects but not let the returned objects run through change-tracking on flush. Any other managed objects are tracked as usual so you can do a read-only query for 100 entities and persist a new entity in the same unit of work with optimal flushing performance. |
| Comments |
| Comment by Konstantin [ 26/Dec/11 ] |
|
Any news? |
| Comment by Gigi Largeanus [ 31/May/12 ] |
|
Any news on this? I think this is a must have feature. Thanks for all your work. |