<!--
RSS generated by JIRA (5.2.7#850-sha1:b2af0c8dc8537b36121c6a579fabbdf79fc919e5) at Fri May 24 04:12:52 UTC 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://www.doctrine-project.org/jira/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml?jqlQuery=labels+%3D+ClassMetadata&tempMax=1000&field=key&field=summary
-->
<!-- If you wish to do custom client-side styling of RSS, uncomment this:
<?xml-stylesheet href="http://www.doctrine-project.org/jira/styles/jiraxml2html.xsl" type="text/xsl"?>
-->
<rss version="0.92">
    <channel>
        <title>Doctrine Project</title>
        <link>http://www.doctrine-project.org/jira/secure/IssueNavigator.jspa?reset=true&amp;jqlQuery=labels+%3D+ClassMetadata</link>
        <description>An XML representation of a search request</description>
                <language>en-us</language>
                        <issue start="0" end="1" total="1"/>
                <build-info>
            <version>5.2.7</version>
            <build-number>850</build-number>
            <build-date>21-02-2013</build-date>
        </build-info>
<item>
            <title>[DDC-2240] Inconsistent querying for parameter type (from ClassMetadata) between using Find/FindBy and DoctrineQL</title>
                <link>http://www.doctrine-project.org/jira/browse/DDC-2240</link>
                <project id="10032" key="DDC">Doctrine 2 - ORM</project>
                        <description>
&lt;p&gt;Hi,&lt;/p&gt;

&lt;p&gt;I have stumbled on a problem were querying the same data with different methods (findBy and DQL) retrieves different results.&lt;/p&gt;

&lt;p&gt;I have extended the Doctrine\DBAL\Types\DateTimeType with my own type&lt;br/&gt;
BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType,&lt;/p&gt;

&lt;p&gt;which I attach.&lt;br/&gt;
I expect, that whenever we deal with an entity that has a property of this type, both convertToDatabaseValue() (whenever we access the DB, conversion from DateTime to a string)  and convertToPHPValue() (whenever the result from DB query is returned back, conversion from string to DateTime) have to be executed.&lt;/p&gt;

&lt;p&gt;It is important, as the single purpose of convertToDatabaseValue() is to perform conversion of the incoming DateTime to the UTC timezone prior to conversion to string,&lt;br/&gt;
and then whenever we convert the DB value to DateTime to set it&apos;s timezone not to default value (server local timezone), but to UTC (as the values are stored in UTC).&lt;/p&gt;

&lt;p&gt;Example:&lt;br/&gt;
Query:&lt;br/&gt;
$entity = $em-&amp;gt;getRepository(&apos;BVDPetroleumBundle:FuelCardTransaction&apos;)-&amp;gt;findOneBy(array(&apos;id&apos; =&amp;gt; $id, &apos;processed_datetime&apos; =&amp;gt; new \DateTime(&apos;2011-03-10 23:58:37&apos;)));&lt;/p&gt;

&lt;p&gt;as you see, DateTime object is created without DateTimeZone set, which makes it employ the server&apos;s default timezone (say EST).&lt;/p&gt;

&lt;p&gt;Entity has this property registered as:&lt;br/&gt;
    /**&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;@ORM\Column(type=&quot;utcdatetime&quot;)&lt;br/&gt;
     */&lt;br/&gt;
    public $processed_datetime;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And this datatype is registered with Doctrine through Symfony2 configuration:&lt;br/&gt;
doctrine:&lt;br/&gt;
    dbal:&lt;br/&gt;
        types: &lt;br/&gt;
            utcdatetime: BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType&lt;/p&gt;


&lt;p&gt;Whenever I query the DB, prior to SQL generation, DateTime is getting converted to UTC by UTCDateTimeType#convertToDatabaseValue(), and becomes:&lt;br/&gt;
&apos;2011-03-10 23:58:37&apos; (EST) -&amp;gt; &apos;2011-03-11 04:58:37&apos; (UTC).&lt;br/&gt;
Then, whenever the object is retrieved back, I expect that UTCDateTimeType#convertToPHPValue() is used to set the correct timezone information&lt;br/&gt;
on the created DateTime object: &apos;2011-03-11 04:58:37&apos; (UTC).&lt;br/&gt;
This is the correct behaviour that is expected, and is correctly achieved by using findBy methods to retrieve data:&lt;/p&gt;

&lt;p&gt;$entity = $em-&amp;gt;getRepository(&apos;BVDPetroleumBundle:FuelCardTransaction&apos;)-&amp;gt;findOneBy(array(&apos;id&apos; =&amp;gt; $id, &apos;processed_datetime&apos; =&amp;gt; new \DateTime(&apos;2011-03-10 23:58:37&apos;)));&lt;/p&gt;

&lt;p&gt;But, when the DQL is used to issue the same query:&lt;/p&gt;

&lt;p&gt;$queryBuilder = $em-&amp;gt;createQueryBuilder()&lt;del&gt;&amp;gt;select(&apos;a&apos;)&lt;/del&gt;&amp;gt;from(&apos;BVDPetroleumBundle:FuelCardTransaction&apos;,&apos;a&apos;)&lt;br/&gt;
-&amp;gt;where(&apos;a.id = :transaction_id&apos;)&lt;br/&gt;
-&amp;gt;andWhere(&quot;a.processed_datetime = :datetime&quot;)&lt;br/&gt;
-&amp;gt;setParameter(&apos;transaction_id&apos;, $id)&lt;br/&gt;
-&amp;gt;setParameter(&quot;datetime&quot;, new \DateTime(&apos;2011-03-10 23:58:37&apos;));&lt;br/&gt;
$entity = $queryBuilder-&amp;gt;getQuery()-&amp;gt;getOneOrNullResult();&lt;/p&gt;

&lt;p&gt;Doctrine\DBAL\Types\DateTimeType#convertToDatabaseValue() is getting executed for &apos;processed_datetime&apos;, instead of &lt;br/&gt;
BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType,&lt;/p&gt;

&lt;p&gt;and the conversion doesn&apos;t happen, so the query doesn&apos;t return the result, that really exists in DB.&lt;/p&gt;

&lt;p&gt;I attach two methods traces, so it&apos;s easier to identify the problem: whenever the findBy is used, and whenever the DQL is used.&lt;br/&gt;
I have managed to trace it to the way how both methods retrieve their $types arrays.&lt;/p&gt;

&lt;p&gt;The reason it succeeds when used with findBy methods:&lt;br/&gt;
Doctrine\ORM\Persisters\BasicEntityPersister#load() is used to retrieve the data.&lt;br/&gt;
The $types property that holds the type information (&apos;utcdatetime&apos;) is formed by calling&lt;br/&gt;
BasicEntityPersister#expandParameters($criteria), and in the process of analyzing incoming parameters it queries the entity metadata (@ORM\Column(type=&quot;utcdatetime&quot;)),&lt;br/&gt;
stored in BasicEntityPersister#$_class property. (method BasicEntityPersister#getType())&lt;br/&gt;
Then it&apos;s able to match type &apos;utcdatetime&apos; to class BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType&lt;/p&gt;

&lt;p&gt;The reason it fails with DQL:&lt;br/&gt;
It seems that with DQL, it doesn&apos;t query the entity metadata (@ORM\Column(type=&quot;utcdatetime&quot;)) to derive property type. This mechanism leads the type to be recognized as simply &apos;datetime&apos;, and the standard handler Doctrine\DBAL\Types\DateTimeType is used instead:&lt;/p&gt;

&lt;p&gt;The $types (which has &apos;datetime&apos; instead of &apos;utcdatetime&apos;) array is getting formed in&lt;br/&gt;
Doctrine\ORM\Query#_doExecute(): &lt;br/&gt;
list($sqlParams, $types) = $this-&amp;gt;processParameterMappings($paramMappings); &lt;/p&gt;

&lt;p&gt;in Doctrine\ORM\Query#processParameterMappings($paramMappings) &lt;br/&gt;
Doctrine\ORM\Query#processParameterValue($parameter-&amp;gt;getValue()) is called to convert parameter from Object to string.&lt;/p&gt;

&lt;p&gt;in Doctrine\ORM\AbstractQuery#processParameterValue($value) for object of class DateTime I would expect this to be executed:&lt;br/&gt;
case is_object($value) &amp;amp;&amp;amp; $this-&amp;gt;_em-&amp;gt;getMetadataFactory()-&amp;gt;hasMetadataFor(ClassUtils::getClass($value)):&lt;br/&gt;
  return $this-&amp;gt;convertObjectParameterToScalarValue($value);  &lt;/p&gt;

&lt;p&gt;but it&apos;s not, and the DateTime is returned out of it, and in Doctrine\ORM\Query\processParameterMappings $type is getting set to $parameter-&amp;gt;getType() (&apos;datetime&apos;)&lt;/p&gt;


&lt;p&gt;Please confirm/contradict the issue. Right now for workaround, whenever I use DQL, have to explicitly set the timezone of DateTime prior to issuing a query.&lt;/p&gt;

&lt;p&gt;From Russia with love,&lt;br/&gt;
Slavik&lt;/p&gt;</description>
                <environment></environment>
            <key id="14380">DDC-2240</key>
            <summary>Inconsistent querying for parameter type (from ClassMetadata) between using Find/FindBy and DoctrineQL</summary>
                <type id="1" iconUrl="http://www.doctrine-project.org/jira/images/icons/issuetypes/bug.png">Bug</type>
                                <priority id="3" iconUrl="http://www.doctrine-project.org/jira/images/icons/priorities/major.png">Major</priority>
                    <status id="5" iconUrl="http://www.doctrine-project.org/jira/images/icons/statuses/resolved.png">Resolved</status>
                    <resolution id="3">Duplicate</resolution>
                    <security id="10000">All</security>
                        <assignee username="beberlei">Benjamin Eberlei</assignee>
                                <reporter username="slavik2121">Slavik Derevyanko</reporter>
                        <labels>
                        <label>ClassMetadata</label>
                        <label>dql</label>
                    </labels>
                <created>Fri, 11 Jan 2013 23:26:13 +0000</created>
                <updated>Fri, 8 Feb 2013 14:36:22 +0000</updated>
                    <resolved>Sun, 13 Jan 2013 08:34:23 +0000</resolved>
                            <version>2.3.1</version>
                                                <component>DQL</component>
                        <due></due>
                    <votes>0</votes>
                        <watches>3</watches>
                        <comments>
                    <comment id="19283" author="slavik2121" created="Fri, 11 Jan 2013 23:57:05 +0000"  >&lt;p&gt;I realized, that with DQL,&lt;br/&gt;
the default type &apos;datetime&apos; of Doctrine\ORM\Query\Parameter for DateTime objects&lt;br/&gt;
is getting set&lt;br/&gt;
by Doctrine\ORM\Query\ParameterTypeInferer#inferType(),&lt;/p&gt;

&lt;p&gt;and that it&apos;s possible to set the type as a third parameter:&lt;/p&gt;

&lt;p&gt;        $queryBuilder = $em-&amp;gt;createQueryBuilder()&lt;br/&gt;
            -&amp;gt;select(&apos;a&apos;)&lt;br/&gt;
            -&amp;gt;from(&apos;BVDPetroleumBundle:FuelCardTransaction&apos;,&apos;a&apos;)&lt;br/&gt;
            -&amp;gt;where(&apos;a.id = :transaction_id&apos;)&lt;br/&gt;
            -&amp;gt;andWhere(&quot;a.processed_datetime = :datetime&quot;)&lt;br/&gt;
            -&amp;gt;setParameter(&apos;transaction_id&apos;, $id)&lt;br/&gt;
            -&amp;gt;setParameter(&quot;datetime&quot;, new \DateTime(&apos;2011-03-10 23:58:37&apos;), &apos;utcdatetime&apos;);&lt;/p&gt;

&lt;p&gt;It seems, this is worth noting in the documentation.&lt;/p&gt;
</comment>
                    <comment id="19287" author="beberlei" created="Sat, 12 Jan 2013 09:13:06 +0000"  >&lt;p&gt;Verified, but I don&apos;t know how to fix it without breaking BC.&lt;/p&gt;

&lt;p&gt;As a workaround you can convert the value yourself in your code, not the nicest solution, but when wrapped in a function call of your own, it shouldn&apos;t be to invasive.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.doctrine-project.org/jira/secure/ViewProfile.jspa?name=guilhermeblanco&quot; class=&quot;user-hover&quot; rel=&quot;guilhermeblanco&quot;&gt;Guilherme Blanco&lt;/a&gt; any idea what to do? &lt;/p&gt;</comment>
                    <comment id="19293" author="guilhermeblanco" created="Sat, 12 Jan 2013 15:55:54 +0000"  >&lt;p&gt;There&apos;s a way currently to fix this issue.&lt;br/&gt;
Of course that we lack of some direct support, but you can take advantage of a second method to fix your problem.&lt;/p&gt;

&lt;p&gt;Currently, &lt;tt&gt;setParameter&lt;/tt&gt; only accepts key, value, type as arguments, creating its own Query\Parameter.&lt;br/&gt;
But if you look at &lt;tt&gt;setParameters&lt;/tt&gt; receiving an ArrayCollection, it doesn&apos;t create the Parameter. This is where you can take advantage.&lt;/p&gt;

&lt;p&gt;Ideally, any Type could convert back and forth from DB to PHP value. During a query, the algorithm should apply also. But if we do this change, we will introduce a BC break. To solve the issue, you&apos;ll have to create your own Parameter.&lt;/p&gt;

&lt;p&gt;From the Doctrine perspective, we only need to support $key to be a class too. If it&apos;s a class, replace the value in the collection of parameters. This is the required change in our codebase.&lt;br/&gt;
But until this gets done, &lt;tt&gt;setParameters&lt;/tt&gt; is already compatible with the solution.&lt;/p&gt;

&lt;p&gt;All you have to do is create a class that extends Query\Parameter, then apply your required changes when doing getValue or during object construction. Then use the method I mentioned to inject an ArrayCollection of Parameters and everything will work. =)&lt;/p&gt;</comment>
                    <comment id="19295" author="beberlei" created="Sun, 13 Jan 2013 08:34:23 +0000"  >&lt;p&gt;Same as &lt;a href=&quot;http://www.doctrine-project.org/jira/browse/DDC-2224&quot; title=&quot;convertToDatabaseValueSQL() is not honored for DQL query parameters&quot;&gt;&lt;del&gt;DDC-2224&lt;/del&gt;&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="19487" author="beberlei" created="Fri, 8 Feb 2013 09:58:55 +0000"  >&lt;p&gt;A related Github Pull-Request &lt;span class=&quot;error&quot;&gt;&amp;#91;GH-574&amp;#93;&lt;/span&gt; was opened&lt;br/&gt;
&lt;a href=&quot;https://github.com/doctrine/doctrine2/pull/574&quot; class=&quot;external-link&quot;&gt;https://github.com/doctrine/doctrine2/pull/574&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="19496" author="slavik2121" created="Fri, 8 Feb 2013 14:36:22 +0000"  >&lt;p&gt;Great, thanks!&lt;/p&gt;</comment>
                </comments>
                <issuelinks>
                        <issuelinktype id="10000">
                <name>Duplicate</name>
                                                <inwardlinks description="is duplicated by">
                            <issuelink>
            <issuekey id="14350">DDC-2224</issuekey>
        </issuelink>
                    </inwardlinks>
                            </issuelinktype>
                    </issuelinks>
                <attachments>
                    <attachment id="11371" name="DoctrineQL methods trace.png" size="162532" author="slavik2121" created="Fri, 11 Jan 2013 23:26:14 +0000" />
                    <attachment id="11372" name="findBy methods trace.png" size="143909" author="slavik2121" created="Fri, 11 Jan 2013 23:26:14 +0000" />
                    <attachment id="11370" name="UTCDateTimeType.php" size="2101" author="slavik2121" created="Fri, 11 Jan 2013 23:26:13 +0000" />
                </attachments>
            <subtasks>
        </subtasks>
        </item>
</channel>
</rss>