[DDC-945] Crashing Bug: BasicEntityPersister::_getSelectColumnListSQL returns empty list, thus generating wrong SQL Created: 22/Dec/10  Updated: 14/Apr/12  Resolved: 28/Dec/10

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

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


 Description   

I have a situation where Doctrine generates a wrong SQL query and crashes with an exception.

The userland code calls the EntityManager::merge method.

The query generated looks like "SELECT FROM SomeTable", meaning it has no select column list, and therefore it's plainly wrong.

The entity I am trying to merge back into the entity manager is a regular entity with state detached. The class has a column which is declared as ID and filled with an autogenerated value, three regular columns, and a one-to-many relationship. The to-many-relationship causes BasicEntityPersister::loadOneToManyCollection() to be called, which in turn calls BasicEntityPersister::_getSelectEntitiesSQL, which then calls BasicEntityPersister::_getSelectColumnListSQL, which wrongly returns an empty string, thus leading to the corrupt query without a select column list being generated. The target entity of the one-to-many relationship is a mapped superclass, which has an ID (again with autogenerated values), and a many-to-one relationship inversing the one in the first entity. Further fields depend on its exact type as determined by the inheriting entities, but it will always have some.

Here is the exception, up to the point where the trace leaves the ORM:

exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM VersionedDataObject t0' at line 1' in /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/DBAL/Connection.php:577 Stack trace: #0 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/DBAL/Connection.php(577): PDO->query('SELECT FROM Ve...') #1 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/Persisters/BasicEntityPersister.php(1173): Doctrine\DBAL\Connection->executeQuery('SELECT FROM Ve...', Array) #2 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1984): Doctrine\ORM\Persisters\BasicEntityPersister->loadOneToManyCollection(Array, Object(persistentData\model\versioning\InputComponentDataVersion), Object(Doctrine\ORM\PersistentCollection)) #3 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/PersistentCollection.php(207): Doctrine\ORM\UnitOfWork->loadCollection(Object(Doctrine\ORM\PersistentCollection)) #4 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1441): Doctrine\ORM\PersistentCollection->initialize() #5 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1323): Doctrine\ORM\UnitOfWork->doMerge(Object(persistentData\model\versioning\InputComponentDataVersion), Array) #6 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/EntityManager.php(520): Doctrine\ORM\UnitOfWork->merge(Object(persistentData\model\versioning\InputComponentDataVersion))

This one is a blocker by user standards. The error means that it is impossible to use Doctrine in long-running batch jobs like in my situation, because it does not support merging certain detached objects back into the entity manager at all, while at some point they need to be detached for virtual memory capacity reasons.



 Comments   
Comment by Daniel Alvarez Arribas [ 22/Dec/10 ]

Added a more accurate description of both entities involved.

Comment by Benjamin Eberlei [ 22/Dec/10 ]

This is not enough information to reproduce this issue. We have tests that show merge and detach works. I need more code, mapping files and a reproduce set.

If yo udont want to attach it to the issue you can send me a mail.

Comment by Daniel Alvarez Arribas [ 25/Dec/10 ]

After analyzing the problem further, I think it is nothing but a subsequent error due to the bidirectional association in the mapped superclass, which is documented to not work in the first place, as relationships declared in mapped superclasses must be unidirectional. After changing the mapped superclass to a regular entity, the application is working.

The only remaining problem in this case is the crashing effect. This is due to the rudimentary data model validation combined with the total lack of decent error messages in Doctrine 2. As there is no apparent relationship between the symptom (exception due to incorrect SQL being generated) and the effective technical source of the problem (bidirectional relationship declared in a mapped superclass), it is unnecessarily cumbersome to determine what possible sources of error to look for. It would be great if doctrine could defend itself against non-conforming data model inputs by producing an understandable error message instead of just crashing.

I will leave this bug open as a validation issue.

Comment by Benjamin Eberlei [ 27/Dec/10 ]

Yeah this is annoying, i check if we can implement a cheap runtime validation when loading the class metadata.

Comment by Benjamin Eberlei [ 28/Dec/10 ]

Throwing mapping exception if using a mapped superclass with ManyToMany or OneToMany association now.

Comment by Daniel Alvarez Arribas [ 29/Dec/10 ]

Thanks for fixing this.

Shouldn't it actually only throw an exception when using bidirectional associations with a mapped superclass?

Comment by Benjamin Eberlei [ 31/Dec/10 ]

Not exactly but you are right, unidirectional Many To Many associations work if you use the Mapped Superclass only once. I will adjust the patch accordingly.

For 2.1 there will be an additional feature described in DDC-964 that allows overriding certain mapped superclass details to avoid these problems.

Comment by Benjamin Eberlei [ 31/Dec/10 ]

Corrected.

Comment by Benjamin Eberlei [ 22/Mar/12 ]

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

Comment by Benjamin Eberlei [ 14/Apr/12 ]

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





[DDC-1019] Double quotation mark mysql query error on orm:convert-mapping --from-database Created: 07/Feb/11  Updated: 07/Feb/11  Resolved: 07/Feb/11

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

Type: Bug Priority: Major
Reporter: Bernhard Schlas Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None
Environment:

ubuntu 10.10 32bit; PHP Version => 5.3.3-1ubuntu9.3; mysql Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (i686) using readline 6.1; Doctrine 2.0.1 git version


Issue Links:
Duplicate
duplicates DBAL-85 Illegal quotes in SHOW FULL TABLES WH... Resolved

 Description   

By executing this command php doctrine orm:convert-mapping --from-database yml yaml/ I get this error:

 
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'BASE TABLE' in 'where clause'' in doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php:577
Stack trace:
#0 doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php(577): PDO->query('SHOW FULL TABLE...')
#1 doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php(532): Doctrine\DBAL\Connection->executeQuery('SHOW FULL TABLE...', Array)
#2 doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php(194): Doctrine\DBAL\Connection->fetchAll('SHOW FULL TABLE...')
#3 doctrine2-orm/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php(76): Doctrine\DBAL\Schema\AbstractSchemaManager->listTableNames()
#4 doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php on line 577

After var_dump the $query variable doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php on line 577 string(48) "SHOW FULL TABLES WHERE Table_type = "BASE TABLE"" you can see that BASE TABLE is in double quotations marks.
I replaced them with single quotation marks SHOW FULL TABLES WHERE Table_type = 'BASE TABLE' and executed the statement on the mysql server, no error!

Please replace the double quotation marks in the query with single quotation marks.



 Comments   
Comment by Benjamin Eberlei [ 07/Feb/11 ]

This is a duplicate of DBAL-85





[DDC-892] Caches can potentially return false positives due to use of MD5 hash codes as keys. A classic. Created: 25/Nov/10  Updated: 23/Jan/11  Resolved: 23/Jan/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0.1, 2.1
Security Level: All

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


 Description   

I was just checking the execution path for efficiency and bumped into this block of code in /Doctrine/ORM/AbstracQuery.php,
starting on line 560:

protected function _getResultCacheId()
{
if ($this->_resultCacheId)

{ return $this->_resultCacheId; }

else

{ $sql = $this->getSql(); ksort($this->_hints); return md5(implode(";", (array)$sql) . var_export($this->_params, true) . var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode); }

}

Of course, MD5 hashes can never be guaranteed to be unique, so this block of the doExecute-Method
starting on line 508 can return false positives and thus break the user's assumptions about the ORM's behavior:

// Check result cache
if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
$id = $this->_getResultCacheId();
$cached = $this->_expireResultCache ? false : $cacheDriver->fetch($id);

if ($cached === false)

{ // Cache miss. $stmt = $this->_doExecute(); $result = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll( $stmt, $this->_resultSetMapping, $this->_hints ); $cacheDriver->save($id, $result, $this->_resultCacheTTL); return $result; }

else

{ // Cache hit. return $cached; }

}

It is not likely to happen, but possible. Rely on it a couple of million times in a production system, and one day, eventually, it will fail
and hell will break loose.

I think it is prohibitive to try to save memory by giving up correctness. If your program does not work, it's simply broken and there is no need to tune it unless you fix it functionally.

The only safe solution would be to use a non-lossy hash (i. e. compression) method, if any. Plain query text would do fine too.

Unless you expect the user to anticipate false positives, i. e.



 Comments   
Comment by Daniel Alvarez Arribas [ 25/Dec/10 ]

Has anyone taken note of this one?

As it seems, this critical bug has been sitting here for a month, untouched, and apparently even made it into the final release.

I would offer to fix it myself, but as the fix would consist in removing just one or two MD5 hash method calls, and it would probably have to be validated anyway by a core developer, there is actually not much technical effort I could save you.

Just a reminder, thanks for your time.

Comment by Benjamin Eberlei [ 27/Dec/10 ]

The problem is rather that cache keys have a limited length depending on the cache driver.I know that Memcache limits at 255, have to look at the others.

Plain Text is not a solution, but we could build a range of several md5 or sha1 hashes to reduce the risk of false/positives even more.

Comment by Daniel Alvarez Arribas [ 29/Dec/10 ]

Hey Ben,

thanks for taking care.

I see the point about the length limitation. Still, I believe is a bad thing to subject correctness to probability considerations. Merely making it more unlikely to happen would only procrastinate a definite solution. Staying with a solution that relies on hash values being unique, is gambling with the probability of software systems malfunctioning randomly for no apparent reason, which is not a desirable outcome.

I figured out an alternate approach that IMO solves the length limit issue, while, to my knowledge, being correct. This is my first shot at it. But right now I do not see why this, or something like it, should not be feasible.

You could keep on indexing by MD5 hash value (just to guarantee an upper bound on the key length and circumvent the limits regarding the maximum key length). I think MD5 does that part quite well. But instead of just storing the value, store a map, mapping all of the original full-length keys that resolve to that common MD5 hash value to their individual values. In almost all but a few very rare cases, this map will have exactly one entry. Therefore in almost all cases, all that is retrieved from the cache is the value, plus the original key, enclosed in a map wrapper object. Needless to say, this map can be optimized for one entry. It could even be a list, with only a few bytes overhead. This solution would be almost as fast for read accesses as the most naïve cache implementation, but still work in cases where keys resolve to the same hash value.

The details are easy:

Fetching: Fetch the cache entry (the map) by the key's MD5 hash value. Then, look the correct value up in the map using the full-length key. Remember this is not any expensive operation. The map contains almost always exactly one value.

Creating: Fetch the cache entry (the map) by the key's MD5 hash value. If there is no cache entry at all, create a new map with a single entry in it and store it into the cache. If there is an entry, get the map, add the new entry to it using the full-length key and the value, and store the map back into the cache using the key's MD5 hash value. Adding a value to the map would also replace any existing entry for the full-length key in case it is already present in the map.

Deleting: Fetch the cache entry (the map) by the key's MD5 hash value. Then, use the full-length key to delete the corresponding value from the map. If the map is empty after removing the entry (and it will be almost always), delete the whole cache entry using the key's MD5 hash value.

This technique is correct always, and gives almost no overhead for reads. For writes and deletes, you have to fetch first, so there is an overhead, but right now I can't come up with anything faster
that isn't broken.

An optimization would be implementing an additional direct full-key mapping, too, for those cache providers supporting arbitrary length keys. This could give slightly better write performance when arbitrary-length keys are supported, as there would not be any map to be read in case of writing and deleting, just a direct cache operation.

Comment by Benjamin Eberlei [ 30/Dec/10 ]

The unhashed key could potentially be very large, which could lead to problems with the value limit of the caches. Plus the unhashed value relies on print_r(), thus on whitespace formatting which i wouldn't call exactly reliable.

We need to find a better solution to fix this

Comment by Daniel Alvarez Arribas [ 01/Jan/11 ]

As for the size limit on cached values, I think it is an independent problem, because any value size limit applies in any case, whether or not you implement unique keys or not. Currently, it also applies e. g. to query results, for which an upper size limit can not be guaranteed in general. Consequently, a strategy for handling such a limit is required anyway.

The naïve solution for handling the value size limit would be to simply not cache any values with a total size larger than the value size limit of the respective cache. As the value size limit should actually be reasonably large (memcached e.g. has a default limit of 1 MB), and the limitation is inherent to the cache, this should be perfectly plausible, because it is the caches key functionality that imposes the limit, not Doctrine. I believe the naïve solution is on-the-spot here, and would recommend to strictly opt against taking further measures (like splitting cache entries into buckets) to work around the problem. Working around this limit should have been implemented in the respective cache in the first place, not in Doctrine, as it concerns the caches key functionality. IMO the ORM should not duplicate cache functionality, rather use it in a proper way.

But after all, this is an unrelated problem, and it does not affect the point of this bug in any way.

As for the reliance on print_r: If you consider it to be non-deterministic (producing different output formattings for identical objects) it would be broken (possibly by design). That being said, I do not believe print_r() is non-deterministic by design, though the exact workings of it might not be formally specified. The formatting in the return value string should not introduce ambiguity into the representations of otherwise unique values, and neither produce different values for identical objects. As long as these conditions are met, you should be safe using it for generating cache keys. If not, use something that does fit. This is a mere implementation issue, anyway. You could also strip whitespaces (provided this does not affect uniqueness), to eliminate the whitespace factor.

If cache size efficiency of stored values is an issue, you could be well-advised to support compressing cache values (losslessly, of course) as an option.

Comment by Benjamin Eberlei [ 05/Jan/11 ]

Ok, the common recommendation to avoid cache collisions is using a multitude of different hashes and combine them, or use a very large hash.

So the best solution here is probably to switch to a cache key that has "sha1 + md5 + crc32" of the input and if ext/hash is installed use something much more powerful like sha256.

Comment by Daniel Alvarez Arribas [ 05/Jan/11 ]

That "recommendation" you are referring to might be just the common practice of using a combination of various hash values to increase the accuracy of ensuring data integrity and authenticity (e.g. by providing various different hash values for downloaded files). IMO this practice is feasible only for purposes like those, and can not be relied on if what you want to do is obtain correct results on cache lookups. While a change in hash value means that the file has definitely been modified (compared to the original) it does not imply e. g. that various modified files that have the same hash value have actually the same modified content.

What you are trying to do could be used in situations where a Bloom Filter (http://en.wikipedia.org/wiki/Bloom_filter) could be appropriately used, which is basically such a combination of various hashes. This could perfectly be used to determine whether there is a high chance that a specific value is in the cache. Such information could be useful to optimize disk accesses or costly requests to remote caches. Bloom filters are used e.g. in the Squid Caching HTTP Proxy, but certainly not for keying, rather for cache digests (read: "is it likely that this key is in the cache?"). This is not the case with the Doctrine 2 caches - these should better be 100% reliable.

Increasing the number or size of hash values will just decrease the probability of a crash, but will not ultimately fix the problem (unless you make the hash values include all original information, but that would be pointless in the first place). And that something is unlikely to happen does not mean it will necessarily take a long time to actually happen. It could as well break an application tomorrow.

Seriously, I do not know of any theoretically backed recommendation that tolerates wrong results when correctness is expected. There are a couple of approximation techniques appropriate in situations where false positives are anticipated, but I believe no such technique would be an appropriate solution for your situation, simply because no one expects the programming contract to imply having to anticipate false positives.

But of course, various hashes would still be better than one, though still worth a bug. Personally I would always opt for correctness. Do as you like.

Comment by Benjamin Eberlei [ 23/Jan/11 ]

Implemented separate chaining to avoid hash key collisions.





[DDC-958] postLoad event triggering Created: 29/Dec/10  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

Type: Improvement Priority: Minor
Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

all



 Description   

Currently I've noticed that postLoad event is not triggered on $em->refresh($entity); it seems like entity should be reloaded on this call
and logically postLoad event should be also triggered if entity is being reloaded.



 Comments   
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed





[DDC-968] Query hints should be retrievable by user Created: 03/Jan/11  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

Type: Improvement Priority: Major
Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

all



 Description   

Currently the only way to set additional parameters accessible by AST TreeWalker is using the query hints.
the main problem is then query is being cloned, hints are flushed and the only way to set them is to access them by name and feed to cloned query one by one.
I think there should be Query::getHints() method available to the userland



 Comments   
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Implemented





[DDC-969] SchemaTool fails with class table inheritance if id columnName is not "id" Created: 05/Jan/11  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

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


 Description   

In method getSchemaFromMetadata() within the $class->isInheritanceTypeJoined() part the following line

Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata() — Line 182
$table->getColumn($class->identifier[0])->setAutoincrement(false);

leads to a Doctrine\DBAL\Schema\SchemaException::columnDoesNotExist() if a columnName other then id is used for the id field, as not the columnName (but the field name) is passed to $table->getColumn().

Should rather be

$table->getColumn($columnName)->setAutoincrement(false);


 Comments   
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed





[DDC-978] Many-To-Many relations are removed after Flush() Created: 12/Jan/11  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

Type: Bug Priority: Critical
Reporter: Thomas G. Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 2
Labels: None

Attachments: File sandbox.rar    
Issue Links:
Duplicate
is duplicated by DDC-983 Creating new collection for manyToMan... Resolved

 Description   

Let's say we have three entities: User, Channel, and Log

Every time a User is created or updated, Channels are assigned to a Many-To-Many collection.
This action gets logged in the Log entity.

I have reproduced the bug in the Doctrine sandbox (see attachment). It's a fully working example.
This is a summary:

This works
// Fetch two channels in an array
$channels = .......

// create a new user and assign channels
$user = new User();
$user->setName('FooBar');
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();
This also works
// Fetch two channels in an array
$channels = .......

// fetch an existing user, *change something to the user*, and assign channels
$user = .............
$user->setName('Gaz');
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();
This does not work (channels are removed)
// Fetch two channels in an array
$channels = .......

// fetch an existing user and only assign channels, change nothing else
$user = .............
$user->setChannels($channels);

//save the user
$em->persist($user);
$em->flush();

// log it
$log = new Log();
$log->setMessage('User created with two channels');
$log->setItem($user);

$em->persist($log);
$em->flush();

This last piece of code generates following SQL code (summarized):

DELETE FROM user_channels WHERE userId = 1
INSERT INTO user_channels (userId, channelId) VALUES (1, 2);
DELETE FROM user_channels WHERE userId = 1

If you remove the $em->flush() after $em->persist($user); in the last example, the code works (channels are persisted).

I did not have this problem with Doctrine2 Alpha4.



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

What do you do in "setChannels"? Do you completly overwrite the previous content of the association variable "User::$channels" ?

Comment by Thomas G. [ 12/Jan/11 ]

I have reproduced the bug in a fully working example. See attachment. Just read instructions in comment and execute each step seperately.

But yes, I overwrite the previous content of the association variable "User::$channels" with a Doctrine ArrayCollection.

User Entity
/** @Entity @Table(name="users") */
class User
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
    /** @Column(type="string", length=50) */
    private $name;

    /**
     * @ManyToMany(targetEntity="Channel")
     * @JoinTable(name="users_channels",
     *          joinColumns={@JoinColumn(name="userId",
                referencedColumnName="id")},
     *          inverseJoinColumns={@JoinColumn(name="channelId",
     *          referencedColumnName="id")}
     *      )
     * @var ArrayCollection
     */
    protected $channels;

    public function __construct(){
        $this->channels = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getChannels() {
        return $this->channels;
    }

    public function setChannels($channels) {
        $channels =  new \Doctrine\Common\Collections\ArrayCollection($channels);
       
        $this->channels = $channels;
    }
}
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed.





[DDC-996] Empty field names lead to weird exception Created: 23/Jan/11  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

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


 Description   

Empty field names (possible in xml and yml) lead to weird exception messages, they should throw a MappingException::missingFieldName exception.



 Comments   
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed





[DDC-960] Locking @Version with MappedSuperClass and Single Table Inheritance results in wrong queries Created: 30/Dec/10  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

Type: Bug Priority: Minor
Reporter: Jack van Galen Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows 7 using Zend Server



 Description   

When using a @version field for locking purposes in one of the fields of a MappedSuperClass, things go wrong. Here is my situation:

SpecificUser extends of BaseUser
There is one mapped superclass containing things like createdOn, createdBy and finally the @version field named version.

Now, when I change a record, the following queries are created. The last one is faulty:

Query: UPDATE specificuser SET firstname = ? WHERE id = ?
Query: UPDATE baseuser SET version = version + 1 WHERE id = ? AND version = ?
Query: SELECT version FROM specificuser WHERE id = ? <======= should be: SELECT version FROM baseuser WHERE id = ?



 Comments   
Comment by Benjamin Eberlei [ 30/Dec/10 ]

You say Single Table Inheritance but specificuser and baseuser are two different tables? How does that work? With single table inheritance both specificuser and baseuser are in the same table.

Can you post your mappings? I am not convinced of this bug yet

Comment by Jack van Galen [ 04/Jan/11 ]

Oops, my mistake. I meant to say 'class table inheritance'. The definitions that I used (slightly modified and translated to English) are below.

Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
 
namespace framework{

	/** @MappedSuperclass */
	class DbTable {

		/**
		 * @Id @Column(type="integer", name="id", length="10", unique="", nullable="")
		 * @GeneratedValue(strategy="AUTO")
		 */
		private $id;

		/** @Version @Column(type="integer", name="version", nullable="true") */
		private $version;
		
		/** @Column(type="datetimetz", name="createdon", nullable="true") */
		private $createdon;

	}
	
}


namespace custom\tables{

	/**
	* @Entity
	*/
	class specificuser extends generated\tables\baseuser {
		
	}

}


namespace custom\tables{

	/**
	 * @Entity
	 * @InheritanceType("JOINED")
	 * @DiscriminatorColumn(name="discr", type="string")
	 * @DiscriminatorMap({"specificuser" = "custom\tables\specificuser"})
	 */
	class baseuser extends generated\tables\baseuser {
	
	}
	
}


namespace generated\tables{

	class specificuser extends custom\tables\baseuser {
	}
	
}


namespace generated\tables{

	class user extends framework\DbTable {

		/**
		*@Column(type="string", nullable="false", unique="true")
		*/
        protected $username;
		
	}
	
}
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed





[DDC-990] Update QueryBuilder reference doc Created: 17/Jan/11  Updated: 23/Jan/11  Resolved: 23/Jan/11

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

Type: Bug Priority: Minor
Reporter: David Buchmann Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

i had a hard time finding how to limit the number of results for querybuilder.

the reference does not say how to do it
http://www.doctrine-project.org/docs/orm/2.0/en/reference/query-builder.html

google brought up that its called setMaxResult, which works fine:
http://www.doctrine-project.org/api/orm/2.0/doctrine/orm/querybuilder.html

maybe the reference is missing more things from the code...

(btw: calling it just limit would have been very intuitive for sql people



 Comments   
Comment by Benjamin Eberlei [ 23/Jan/11 ]

Fixed





[DDC-975] Notice in SchemaTool when using assigned id string without length and auto-join column generation Created: 10/Jan/11  Updated: 13/Jan/11  Resolved: 13/Jan/11

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

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


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

Fixed.





[DDC-980] SQL alias behavior inconsistent in UPDATE ... WHERE (subselect) Created: 13/Jan/11  Updated: 13/Jan/11  Resolved: 13/Jan/11

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

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


 Description   

When using a DQL UPDATE with a subselect in the WHERE clause (such as what the size() function generates), the subselect is trying to reference an alias that is not defined in the main UPDATE clause. Using the size() function similarly in a SELECT statement works fine, the problem is only occurring for me when I try an UPDATE. I have not tried it with INSERT or DELETE, but I would suspect a similar inconsistency with anything other than the more common usage with SELECT.

$q = $em->createQuery('UPDATE Event e SET e.no_speakers = 1, e.no_credits = 1 WHERE size(e.Instances) = 0');
print $q->getSQL();

Output:

UPDATE Event SET no_speakers = 1, no_credits = 1 WHERE (SELECT COUNT(*) FROM Instance c0_ WHERE c0_.Event_id = c1_.id) = 0

And, $q->execute() results in:

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'c1_.id' in 'where clause'' in /var/www/v3-lf/library/Doctrine/DBAL/Connection.php:657
Stack trace: #0 /var/www/v3-lf/library/Doctrine/DBAL/Connection.php(657): PDO->exec('UPDATE Event...')


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

Would something like the following work on ALL database vendors?

UPDATE Event SET no_speakers = 1, no_credits = 1 WHERE (SELECT COUNT(*) FROM Instance c0_ WHERE c0_.Event_id = Event.id) = 0
Comment by Benjamin Eberlei [ 13/Jan/11 ]

It does work. Fixed!





[DDC-949] strange behavior with boolean types when using findOneBy() in a CLI phpunit test Created: 25/Dec/10  Updated: 02/Jan/11  Resolved: 02/Jan/11

Status: Closed
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.0.1, 2.1
Security Level: All

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

Attachments: File DDC949Test.php     File DoctrineORMBugTest.php    

 Description   

I do not see this behavior when running findByOne() calls via the Apache SAPI. No clue really what could possibly cause this. Not sure how to get the error logger to output something in a phpunit test (never really figured out how phpunit supports debugging). Essentially if I run the tests with SQLite the case with 'false' fails and when I run with PostgreSQL the case with 0 fails. Essentially in the fail case I get an instance of $this, just like when I pass: false.

Tell me if this report is useless in the current state and then I will work on separating it out into a standalone CLI script without Symfony2 and phpunit. But I dont want to spend more time on this if it isnt necessary.



 Comments   
Comment by Benjamin Eberlei [ 28/Dec/10 ]

Cannot reproduce.

Comment by Benjamin Eberlei [ 28/Dec/10 ]

Attached simpler testcase for reproduce.

Comment by Lukas Kahwe [ 28/Dec/10 ]

further testing shows this issue only exists with false and there I can reproduce it on the CLI and via apache. it seems I am hitting: http://bugs.php.net/bug.php?id=33876
however the issue also happens with sqlite for the same reason false gets casted to an empty string when not telling PDO explicitly to handle the parameter as a boolean.

Comment by Lukas Kahwe [ 01/Jan/11 ]

as explained in the previous comment, the issue is caused by "false" and not by "true" as in the test case.

Comment by Benjamin Eberlei [ 02/Jan/11 ]

Fixed.

This issue occured, because BasicEntityPersister did not pass the PARAM: typehints to the DBAL connection.

Adding this fixes the issue with Booleans on PostgreSQL, however I just realized it also exists for Oracle OCI and needs an adjustment in DBAL to be fixable.

Comment by Lukas Kahwe [ 02/Jan/11 ]

I am also seeing the issue with SQLite.

Comment by Lukas Kahwe [ 02/Jan/11 ]

ok .. i can confirm the issue is fixed on sqlite and postgresql





[DDC-966] SchemaTool does not check for inherited fields in STI sub-classes and overwrites their column definitions to DEFAULT NULL Created: 01/Jan/11  Updated: 02/Jan/11  Resolved: 02/Jan/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0
Fix Version/s: 2.0.1, 2.1
Security Level: All

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


 Description   
Example
/**
 * @Entity
 * @Table(
 *     name="eav_attribute",
 *     uniqueConstraints={
 *         @UniqueConstraint(columns={"core_project_id", "name"})
 *     }
 * )
 * @InheritanceType(
 *     "SINGLE_TABLE"
 * )
 * @DiscriminatorColumn(
 *     name="datatype",
 *     type="string"
 * )
 * @DiscriminatorMap({
 *     "datetime"="AttributeDatetime",
 *     "decimal"="AttributeDecimal",
 *     "int"="AttributeInt",
 *     "string"="AttributeString",
 *     "text"="AttributeText"
 * })
 */
abstract class AbstractAttribute
{
    // ...
    
    /**
     * @Column(type="string")
     */
    protected $name;

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

    // ...
}

/**
 * @Entity
 */
class AttributeDatetime extends AbstractAttribute
{
}

Expected SQL-dump:

name VARCHAR(255) NOT NULL,
is_unique TINYINT(1) NOT NULL,

SQL-dump created by SchemaTool:

name VARCHAR(255) DEFAULT NULL,
is_unique TINYINT(1) DEFAULT NULL,

This behaviour is problematic, especially for columns which are part of a unique constraint.

Reason:

SchemaTool doesn't really check for inherited fields in STI sub classes in method getSchemaFromMetadata() and passes all fields (incl. the inherited) to method _gatherColumn() where finally the column definition of the parent class will be overwritten.

Doctrine\ORM\Tools\SchemaTool
private function _gatherColumn($class, array $mapping, $table)
{
    // Lines 309 - 311
    if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
        $options['notnull'] = false;
    }
}

A quick fix:

Change that if-clause above to

if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0 && ! isset($mapping['inherited'])) {

Better fix:

Only pass not inherited fields to the _gatherColumn() method, as done with CTI sub classes.



 Comments   
Comment by Benjamin Eberlei [ 02/Jan/11 ]

Fixed

Comment by ayhan [ 02/Jan/11 ]

Wow, that was fast!





[DDC-166] When entity is moved from one collection to another, it is still considered "orphaned" Created: 20/Nov/09  Updated: 02/Jan/11  Resolved: 02/Jan/11

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

Type: Bug Priority: Minor
Reporter: Avi Block Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: None

Attachments: Text File DDC166-2.patch     Text File DDC166.patch    

 Description   

If I remove an entity from a PersistentCollection, the UnitOfWork marks is as "orphaned" (assuming I set that in my entity). If I then move the entity to another collection, this status doesn't get removed, and the UnitOfWork deletes it.



 Comments   
Comment by Benjamin Eberlei [ 27/Dec/10 ]

Hm i think this should be marked as bug

Comment by Benjamin Eberlei [ 27/Dec/10 ]

Attached a patch to fix this issue, but its not really final yet.

Architectural questions:

1. Are PersistentCollection::add() and PersistentCollection::remove() the only cases where unscheduleOrphanRemoval() is necessary? What about simple ArrayCollections on a new entity?
2. What about TO_ONE associations with orphan removal?

Comment by Benjamin Eberlei [ 27/Dec/10 ]

Patch that solves the issue with ArrayCollections that cannot unschedule orphan removals themselves.

Now only the problem with ONE_TO_ONE relation persists. However this means we might need a new UnitOfWork instance variable. The reason for this is that the Orphan removal of ONE_TO_ONE is detected in "UnitOfWork::computeChangeSets". We cannot use the current "UnitOfWork::unscheduleOrphanRemoval" for this, since it would fail on the following ordering problem:

1. Entity B unschedule Orphan Removal
2. Entity A schedule Orphan Removal again (#fail)

Comment by Benjamin Eberlei [ 02/Jan/11 ]

We discussed this issue and came to the conclusion that this behavior is not a bug rather a documentation issue.

Enabling orphanRemoval=true is the semantical equivalent of saying that the orphan entity is privately owned by the parent. That means it should not be re-used!

If you want to re-use entities you should rather look into explicit $em->remove() calls or using cascade=remove.

I updated the documentation accordingly.





[DDC-965] Check for ID in CMF should be done after Event invocation Created: 01/Jan/11  Updated: 02/Jan/11  Resolved: 02/Jan/11

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

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


 Comments   
Comment by Benjamin Eberlei [ 02/Jan/11 ]

Fixed





[DDC-955] PostgresSQL + No identifier / primary key for Specified Entity 'Table'. Every Entity must have for an identifier / primary key. Created: 28/Dec/10  Updated: 30/Dec/10  Resolved: 30/Dec/10

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

Type: Bug Priority: Major
Reporter: John Carlos Espitia Rivera Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None
Environment:

all



 Description   

PostgreSQL error map from reverse engineering is not recognized by the primary keys in PostgreSQL and throws the following error: "No identifier / primary key for Specified Entity 'Table'. Every Entity must have for an identifier / primary key."



 Comments   
Comment by Benjamin Eberlei [ 30/Dec/10 ]

Duplicate of DDC-929





[DDC-874] orm:convert-mapping Created: 10/Nov/10  Updated: 30/Dec/10  Resolved: 30/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0.1, 2.1
Security Level: All

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

Ubuntu 10.10.


Sub-Tasks:
Key
Summary
Type
Status
Assignee
DDC-929 A index has to be named as "primary" ... Sub-task Resolved Benjamin Eberlei  

 Description   

I have a Postgres SQL database.
The Base has only one table "User" with two attributes (name and id).
"Id" is primary key.

The failure to execute the task:
php orm doctrine: convert-mapping - from-database yml / home / cristian / database.yml

is:

[Doctrine \ ORM \ Mapping \ MappingException]
No identifier / primary key for Specified Entity 'User'. Every Entity must have for an identifier / primary key

Script to create the table:

CREATE TABLE "User"
(
id serial NOT NULL,
name character varying (55),
CONSTRAINT "User_pkey" PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
ALTER TABLE "User" OWNER TO postgres;



 Comments   
Comment by Benjamin Eberlei [ 30/Dec/10 ]

Fixed in DDC-929





orm:convert-mapping (DDC-874)

[DDC-929] A index has to be named as "primary" to be detected Doctrine\ORM\Mapping\Driver\DatabaseDriver::loadMetadataForClass() Created: 13/Dec/10  Updated: 30/Dec/10  Resolved: 30/Dec/10

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

Type: Sub-task Priority: Major
Reporter: Jiri Helmich Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

FreeBSD, PostgreSQL 8.4



 Description   

Condition

if (isset($indexes['primary']) && in_array($column->getName(), $indexes['primary']->getColumns())) {

needs the primary key to be named as primary. Discovered this when reverse engineering an existing database.

Fix, that worked for me:

Replace:

if (isset($indexes['primary']) && in_array($column->getName(), $indexes['primary']->getColumns())) {
$fieldMapping['id'] = true;

With:

$primary = false;

foreach ($indexes as $index)
{
if ($index->isPrimary())
{
if (in_array($column->getName(), $index->getColumns()))

{ $primary = true; break; }

}
}

if ($primary){
$fieldMapping['id'] = true;



 Comments   
Comment by Benjamin Eberlei [ 30/Dec/10 ]

Fixed.





[DDC-961] First letters are missing in M:N tables Created: 30/Dec/10  Updated: 30/Dec/10  Resolved: 30/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0
Fix Version/s: 2.0.1, 2.1
Security Level: All

Type: Bug Priority: Minor
Reporter: Jakub Vrána Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows, MySQL



 Description   

When I define M:N relation and update the schema by SchemaTool then the joining table is created without first letters (e.g. rticle_ag instead of article_tag). Relevant part from the source code:

<?php
/** @entity */
class Article {
	/** @manyToMany(targetEntity="Tag") */
	public $tags;
}

/** @entity */
class Tag {
	/** @manyToMany(targetEntity="Article", mappedBy="tags") */
	public $articles;
}

$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$tool->updateSchema(array(
	$em->getClassMetadata('Article'),
	$em->getClassMetadata('Tag'),
));
?>

You can download the complete example at http://www.notorm.com/static/doctrine2-notorm/



 Comments   
Comment by Benjamin Eberlei [ 30/Dec/10 ]

Your entities are not namespaced are they?

Comment by Benjamin Eberlei [ 30/Dec/10 ]

Yes, this is related to entities in global namespaces only. That is why nobody realized it before.

Fixed now.





[DDC-932] Schema problem with Postgresql Created: 13/Dec/10  Updated: 28/Dec/10  Resolved: 28/Dec/10

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

Type: Bug Priority: Major
Reporter: Andy Aja deh Assignee: Roman S. Borschel
Resolution: Invalid Votes: 0
Labels: None
Environment:

Windows XP SP 3
Postgresql 9.0
PHP 5.3


Attachments: File cli-config.php     File Mdp.php     File Sales.Domain.Kendaraan.php     File Sales.Domain.Master.Cabang.php     File Sales.Domain.Mdp.php    

 Description   

Hi, I have a problem when using doctrine 2 with schema in Postgresql.

This is my php mapping:

<?php

use Doctrine\ORM\Mapping\ClassMetadataInfo;

$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
$metadata->setPrimaryTable(array(
    'name' => 'sales.mdp',
));

$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$metadata->setSequenceGeneratorDefinition(array(
        'sequenceName'   => 'sales.mdp_id_seq',
        'allocationSize' => 10,
        'initialValue'   => 1,
    ));
    
$metadata->mapField(array(
   'id'         => true,
   'fieldName'  => 'id',
   'columnName' => 'id',
   'type'       => 'integer',
  ));

I can generate tables successfully with orm:schema-tool:create.
I don't edit anything, and just try to orm:schema-tool:update, the output should be:

Nothing to update. The database is in sync with the current entity metadata.

But I get:

Updating database schema...

  [PDOException]

  SQLSTATE[42P07]: Duplicate table: 7 ERROR:  relation "mdp_id_seq" already exists

my orm:schema-tool:update --dump-sql outputs

CREATE SEQUENCE sales.mdp_id_seq INCREMENT BY 10 MINVALUE 1 START 1;
CREATE TABLE sales.mdp (id INT NOT NULL, rrn VARCHAR(50) NOT NULL, model VARCHAR(255) DEFAULT NULL, tipe VARCHAR(255) DEFAULT NULL, warna VARCHAR(50) DEFAULT NULL, nama_pelanggan VARCHAR(255) DEFAULT NULL, sales VARCHAR(255) DEFAULT NULL, keterangan TEXT DEFAULT NULL, tanggal DATE NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id));
CREATE UNIQUE INDEX sales_mdp_rrn_uniq ON sales.mdp (rrn)

I upload my files in attachment. Please advice, thanks.



 Comments   
Comment by Benjamin Eberlei [ 14/Dec/10 ]

Are you using RC2? If not please try it with RC2, i fixed a bug regarding this just some days ago.

Comment by Andy Aja deh [ 14/Dec/10 ]

Ic, I updated to RC2 and this issue was solved. Thanks Ben.

But now, I get another problem. When I add a new class & mapping with no schema, it is generated in the previous mapped schema.
Is it the way it should works? and if I want to map to public schema, do I need to explicitly write "public.table_name" ?

Here is my new mapping:

<?php

use Doctrine\ORM\Mapping\ClassMetadataInfo;

$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
$metadata->setPrimaryTable(array(
   'name' => 'cabang',
));

$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$metadata->setSequenceGeneratorDefinition(array(
        'sequenceName'   => 'cabang_id_seq',
        'allocationSize' => 10,
        'initialValue'   => 1,
    ));

$metadata->mapField(array(
   'id'         => true,
   'fieldName'  => 'id',
   'columnName' => 'id',
   'type'       => 'integer',
   'unsigned'   => false,
  ));

<?php

use Doctrine\ORM\Mapping\ClassMetadataInfo;

$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
$metadata->setPrimaryTable(array(
   'name' => 'public.kendaraan',
));

$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$metadata->setSequenceGeneratorDefinition(array(
        'sequenceName'   => 'public.kendaraan_id_seq',
        'allocationSize' => 10,
        'initialValue'   => 1,
    ));

$metadata->mapField(array(
   'id'         => true,
   'fieldName'  => 'id',
   'columnName' => 'id',
   'type'       => 'integer',
   'unsigned'   => false,
  ));

I get the following:

The table cabang, is not generated in public schema, but in sales schema (previously mapped sales.mdp), .
The table public.kendaraan is generated correctly,
But even if I write explicitly "public.kendaraan", (I don't edit anything, and just try to orm:schema-tool:update) the --dump-sql still outputs:

CREATE SEQUENCE public.kendaraan_id_seq INCREMENT BY 10 MINVALUE 1 START 1;
CREATE SEQUENCE cabang_id_seq INCREMENT BY 10 MINVALUE 1 START 1;
CREATE TABLE public.kendaraan (id INT NOT NULL, tipe_kendaraan VARCHAR(255) NOT
NULL, warna VARCHAR(255) NOT NULL, no_rangka VARCHAR(255) NOT NULL, no_mesin VARCHAR(255) NOT NULL, tahun INT NOT NULL, rrn VARCHAR(255) NOT NULL, salesman VARCHAR(255) DEFAULT NULL, pelanggan VARCHAR(255) DEFAULT NULL, keterangan VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id));
CREATE UNIQUE INDEX public_kendaraan_no_rangka_uniq ON public.kendaraan (no_rangka);
CREATE UNIQUE INDEX public_kendaraan_no_mesin_uniq ON public.kendaraan (no_mesin);
CREATE UNIQUE INDEX public_kendaraan_rrn_uniq ON public.kendaraan (rrn);
CREATE TABLE cabang (id INT NOT NULL, kode VARCHAR(255) NOT NULL, nama VARCHAR(255) NOT NULL, alamat VARCHAR(255) NOT NULL, PRIMARY KEY(id));
CREATE UNIQUE INDEX cabang_kode_uniq ON cabang (kode);
CREATE UNIQUE INDEX cabang_nama_uniq ON cabang (nama)

Thanks for helping.

Comment by Benjamin Eberlei [ 16/Dec/10 ]

hm, maybe i understand it wrong but arent unqualified tables ALWAYS generated into the public schema?

Executing your code with "CREATE ETABLE kenderaan" (without public. prefix) it still puts it into the public schema, not into sales.

Comment by Andy Aja deh [ 16/Dec/10 ]

Yes, like you said. The unqualified tables should always be generated into public schema. And my cases here are:

1. my unqualified table: cabang is not generated in public schema, but in sales schema.

2. my fully qualified table: public.kendaraan is generated correctly in public schema then I don't edit anything, and just try to orm:schema-tool:update), expected --dump-sql is empty, but I get:

CREATE SEQUENCE public.kendaraan_id_seq INCREMENT BY 10 MINVALUE 1 START 1;
CREATE SEQUENCE cabang_id_seq INCREMENT BY 10 MINVALUE 1 START 1;
CREATE TABLE public.kendaraan (id INT NOT NULL, tipe_kendaraan VARCHAR(255) NOT
NULL, warna VARCHAR(255) NOT NULL, no_rangka VARCHAR(255) NOT NULL, no_mesin VARCHAR(255) NOT NULL, tahun INT NOT NULL, rrn VARCHAR(255) NOT NULL, salesman VARCHAR(255) DEFAULT NULL, pelanggan VARCHAR(255) DEFAULT NULL, keterangan VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id));
CREATE UNIQUE INDEX public_kendaraan_no_rangka_uniq ON public.kendaraan (no_rangka);
CREATE UNIQUE INDEX public_kendaraan_no_mesin_uniq ON public.kendaraan (no_mesin);
CREATE UNIQUE INDEX public_kendaraan_rrn_uniq ON public.kendaraan (rrn);
CREATE TABLE cabang (id INT NOT NULL, kode VARCHAR(255) NOT NULL, nama VARCHAR(255) NOT NULL, alamat VARCHAR(255) NOT NULL, PRIMARY KEY(id));
CREATE UNIQUE INDEX cabang_kode_uniq ON cabang (kode);
CREATE UNIQUE INDEX cabang_nama_uniq ON cabang (nama)
Comment by Benjamin Eberlei [ 28/Dec/10 ]

is your database user named "cabang"? Unqualified is defined by some include path equivalent in PostgreSQL.

Comment by Benjamin Eberlei [ 28/Dec/10 ]

See 5.7.3 here http://www.postgresql.org/docs/current/static/ddl-schemas.html

Comment by Andy Aja deh [ 28/Dec/10 ]

Oic, my database username is "sales", so the unqualified schema is generated in "sales" schema.

Thanks a lot for your help.

Comment by Andy Aja deh [ 28/Dec/10 ]

This is not doctrine's bug, It is my miss understanding about schema search path behavior in postgresql. Thanks.





[DDC-837] Two children in inheritance with same property name causes error in hydration Created: 12/Oct/10  Updated: 28/Dec/10  Resolved: 28/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0.1, 2.1
Security Level: All

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

Attachments: File DDC258Test.php    

 Description   

This is related to DDC-258. The issue seems to be fixed with regular column types (string, int, etc) but the same issue has cropped up when we have a OneToOne relationship in two child classes that share the same property name. I have modified the DDC258TestCase class to demonstrate the error.

To summarize: two classes that inherit from the same class happen to have a property with the same name. Both of them are oneToOne relationships. Querying for the objects, one object type (depending on discriminatorMap order) will be hydrate correctly but the other will always be null.



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

This is not a bug, its documented behavior and is technically not feasible.

Comment by Michael Ridgway [ 13/Oct/10 ]

Why would this not be feasible on relationships even though it is on regular column types? I feel like this is the same issue as DDC-258. I understand a child can't have a property named the same as the parent's, but two children should be able to have properties with the same name (and currently can if it's not a relationship).

Comment by Benjamin Eberlei [ 14/Oct/10 ]

oh maybe i am wrong

Comment by Benjamin Eberlei [ 28/Dec/10 ]

Fixed





[DDC-928] Using uninitialised variable in lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php Created: 13/Dec/10  Updated: 28/Dec/10  Resolved: 28/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-RC2
Fix Version/s: 2.0.1, 2.1
Security Level: All

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

FreeBSD



 Description   

A call:

$metadata->setSequenceGeneratorDefinition($definition);

is performed a line above the definition of the $definition variable.

Fix: Switch those two lines:

// $metadata->setSequenceGeneratorDefinition($definition); //was here
$definition = array(
'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
);
$metadata->setSequenceGeneratorDefinition($definition); //belongs here

On line 191 in RC2 release.



 Comments   
Comment by Benjamin Eberlei [ 28/Dec/10 ]

Fixed





[DDC-617] ObjectHydrator issue with OneToMany relationship Created: 30/May/10  Updated: 28/Dec/10  Resolved: 28/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.0.1, 2.1
Security Level: All

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

XAMPP 1.7.3 on Windows Vista


Attachments: File SocialMediaLink.php     File User.php    

 Description   

I'm pretty new to this ORM thing but I am having a weird issue with a DQL query I think should work (or throw an exception). I have the following code:

namespace Lms\Entities;
/**
 *
 * @Entity
 * @Table(name="User")
 */
class User {

	public function __constructor() {
		$social_media_links = new \Doctrine\Common\Collections\ArrayCollection;
	}
	/**
	 * @Id
	 * @Column(type="bigint")
	 * @GeneratedValue
	 */
	protected $id;

	/** @Column(type="string", nullable=TRUE, length=1024) */
	protected $mission_statement;

	/** @Column(type="string") */
	protected $first_name;

	/** @Column(type="string") */
	protected $last_name;

	/** @Column(type="string", nullable=TRUE, length=8) */
	protected $initial;

	/** @Column(type="string", nullable=TRUE) */
	protected $email;

	/** @Column(type="string", nullable=TRUE) */
	protected $company;

	/** @Column(type="string", nullable=TRUE, length=1024) */
	protected $picture;

	/** @Column(type="text", nullable=TRUE) */
	protected $bio;

	// unidirectional one to many relationship with social media link
	/**
	 * @ManyToMany(targetEntity="SocialMediaLink")
	 * @JoinTable(name="Users_Socialmedialinks",
	 *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
	 *      inverseJoinColumns={@JoinColumn(name="socialmedialink_id", referencedColumnName="id", unique=true)}
	 *      )
	 */
	protected $social_media_links;
	

    /**
     * Add social_media_links
     *
     * @param SocialMediaLink $socialMediaLinks
     */
    public function addSocialMediaLinks(\SocialMediaLink $socialMediaLinks)
    {
        $this->social_media_links[] = $socialMediaLinks;
    }

    /**
     * Get social_media_links
     *
     * @return Doctrine\Common\Collections\Collection $socialMediaLinks
     */
    public function getSocialMediaLinks()
    {
        return $this->social_media_links;
    }
}
namespace Lms\Entities;

/**
 *
 * @Entity
 * @Table(name="SocialMediaLink")
 */
class SocialMediaLink {

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

	/** @Column(type="string") */
	protected $title;

	/** @Column(type="string") */
	protected $link;

}

And when I execute:

		$sml = $this->_em->createQuery("SELECT s FROM Lms\Entities\User u JOIN u.social_media_links  AS s WHERE u.id = ?1 AND s.id = ?2")
					->setParameter(1, 1)
					->setParameter(2, 1)
					->getResult();

I get the following trace:

1) DoctrineExtensions\PHPUnit\UserTestCase::testEditSocialMediaLink
class_parents(): object or string expected

C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Mapping\ClassMetadataFactory.php:201
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Mapping\ClassMetadataFactory.php:224
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Mapping\ClassMetadataFactory.php:148
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\EntityManager.php:235
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php:220
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php:75
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\Internal\Hydration\AbstractHydrator.php:98
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\AbstractQuery.php:530
C:\xampp\htdocs\lms-user-sml-feature\system\application\libraries\Doctrine\ORM\AbstractQuery.php:360

The following data is in the database:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<table name="user">
		<column>id</column>
		<column>mission_Statement</column>
		<column>first_name</column>
		<column>last_name</column>
		<column>initial</column>
		<column>email</column>
		<column>company</column>
		<column>picture</column>
		<column>bio</column>
		
		<row>
			<value>1</value>
			<value>Mission Statement 1</value>
			<value>First Name 1</value>
			<value>Last Name 1</value>
			<value>IN1</value>
			<value>email1@email.com</value>
			<value>Company 1</value>
			<value>Picture 1</value>
			<value>Bio 1</value>
		</row>
	</table>
	
	<table name="socialmedialink">
		<column>id</column>
		<column>title</column>
		<column>link</column>

		<row>
			<value>1</value>
			<value>Social Media Title 1</value>
			<value>Social Media Link 1</value>
		</row>
	</table>
	
	<table name="users_socialmedialinks">
		<column>user_id</column>
		<column>socialmedialink_id</column>

		<row>
			<value>1</value>
			<value>1</value>
		</row>
	</table>
</dataset>


 Comments   
Comment by Numan S [ 30/May/10 ]

After messing around with it a little bit, the following will work:

	
		$sml = $this->_em->createQuery("SELECT u,s FROM Lms\Entities\User u JOIN u.social_media_links AS s WHERE u.id = ?1 AND s.id = ?2")
					->setParameter(1, 1)
					->setParameter(2, 1)
					->getResult();
Comment by Roman S. Borschel [ 07/Aug/10 ]

Hydration does not (yet?) support such kinds of queries where the root entity/schema name is not selected.

Comment by Benjamin Eberlei [ 15/Sep/10 ]

@roman i think this should be solved in conjunction with DDC-736 and throw an exception if the users tries to do this. Is this possible in linear time?

Comment by Benjamin Eberlei [ 28/Dec/10 ]

Fixed, a QueryException will now be thrown if attempting to select one or more identification variables without picking at least one root.





[DDC-931] SchemaTool->dropSchema fails if the given schema doesn't exist Created: 13/Dec/10  Updated: 22/Dec/10  Resolved: 22/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-RC2
Fix Version/s: 2.0.1, 2.1
Security Level: All

Type: Bug Priority: Major
Reporter: Timo A. Hummel Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

SchemaTool->dropSchema's documentation says:

 
Drops the database schema for the given classes.

In any way when an exception is thrown it is supressed since drop was issued for all classes of the schema and some probably just don't exist.

However, with a recent upgrade to 2.0-RC2, this doesn't work anymore. A PDO exception isn't caught if the specified table doesn't exist already.

 
exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1051 Unknown table 'UserAddress'' in /usr/share/php/Doctrine/DBAL/Connection.php:577

I'm not sure if this was caused by the ORM update or if it's maybe somewhere inside DBAL, which I upgraded at the same time.



 Comments   
Comment by Benjamin Eberlei [ 22/Dec/10 ]

Fixed





[DDC-944] MappingException::mappingNotFound() calls are wrong in ClassMetadataInfo Created: 21/Dec/10  Updated: 21/Dec/10  Resolved: 21/Dec/10

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

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


 Description   

As you can see in:
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
and:
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/MappingException.php
mappingNotFound() accepts now only 1 argument, but is called with 2; this leads to cryptic errors when the a field does not exist like:
Doctrine\ORM\Mapping\MappingException: No mapping found for field 'EntityClassName'



 Comments   
Comment by Benjamin Eberlei [ 21/Dec/10 ]

Fixed





Generated at Mon Sep 22 20:30:31 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.