Bonjour à tous,

J'ai un légé soucis pour utiliser les requêtes DQL avec Doctrine....


J'ai un modèle de données comme suite :

- Table :
- tracked_object (id auto-inc, informations de màj de la donnée)
- localized_value (id liée à tracked_object et code)
- system_value (id liée à localized_value avec commentaire et ordre)
- translation (id auto inc, fk localized_value, fk system_value pour la locale et valeur traduite)

- Entities :
- TrackedObject
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @version    SVN:$Id: TrackedObject.php 2 2013-02-13 10:44:11Z 16660 $
 * @author     16660
 */
namespace Gdp\Entity;
 
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\PostPersist;
use Doctrine\ORM\Mapping as ORM;
use \Gdp\Doctrine\DBAL\Types;
use \Gdp\Entity\TrackedObject;
use \Gdp\Entity\TrackedObject\LocalizedValue;
 
 
/**
 * TrackedObject
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @author     16660
 * @version    Release:1.0
 * 
 * @ORM\Table(name="tracked_object")
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="system_type_id")
 * @ORM\DiscriminatorMap({
 * 	"1" = "Gdp\Entity\TrackedObject", 
 * 	"2" = "Gdp\Entity\TrackedObject\LocalizedValue", 
 * 	"3" = "Gdp\Entity\TrackedObject\LocalizedValue\SystemValue", 
 *  "4" = "Gdp\Entity\TrackedObject\LocalizedValue\SystemValue\Locale"
 *  })
 * @ORM\HasLifecycleCallbacks
 */
class TrackedObject
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
 
    /**
     * @var \Zend_Date
     *
     * @ORM\Column(name="creation_date", type="zenddate", nullable=false)
     */
    private $_creationDate;
 
    /**
     * @var \User
     *
     * @ORM\Column(name="creator_id", type="string", length=100, nullable=false)
     */
    private $_creator;
 
    /**
     * @var \Zend_Date
     *
     * @ORM\Column(name="update_date", type="zenddate", nullable=true)
     */
    private $_updateDate;
 
    /**
     * @var \User
     *
     * @ORM\Column(name="updator_id", type="string", length=100, nullable=true)
     */
    private $_updator;
 
    /**
     * Constructor
     */
    public function __construct()
    {
 
    }
 
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
 
    /**
     * Get creationDate
     *
     * @return \Zend_Date 
     */
    public function getCreationDate()
    {
        return $this->_creationDate;
    }
 
    /**
     * Get creator
     *
     * @return \User 
     */
    public function getCreator()
    {
        return $this->_creator;
    }
 
    /**
     * Get updateDate
     *
     * @return \Zend_Date 
     */
    public function getUpdateDate()
    {
        return $this->_updateDate;
    }
 
    /**
     * Get updator
     *
     * @return \User 
     */
    public function getUpdator()
    {
        return $this->_updator;
    }
 
    /**
     * @ORM\PrePersist
     * @return void
     */
    public function prePersist()
    {
    	$this ->_creationDate = new \Zend_Date();
    	$this -> _creator = \Zend_Registry::get(\Nsf_Application_Resource_Loggeduser::DEFAULT_REGISTRY_KEY);
    }
 
    /**
     * @ORM\PreUpdate
     * @return void
     */
    public function preUpdate()
    {
    	$this ->_updateDate = new \Zend_Date();
    	$this -> _updator = \Zend_Registry::get(\Nsf_Application_Resource_Loggeduser::DEFAULT_REGISTRY_KEY);
    }
}
- LocalizedValue
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @version    SVN:$Id: LocalizedValue.php 2 2013-02-13 10:44:11Z 16660 $
 * @author     16660
 */
namespace Gdp\Entity\TrackedObject;
 
use Gdp\Entity\TrackedObject;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * LocalizedValue
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @author     16660
 * @version    Release:1.0
 * 
 * @ORM\Table(name="localized_value")
 * @ORM\Entity
 * 
 */
class LocalizedValue extends TrackedObject
{
    /**
     * @var string
     *
     * @ORM\Column(name="code", type="string", length=100, nullable=false)
     */
    private $code;
 
    /**
     * @var integer
     *
     * @ORM\Column(name="status", type="integer", nullable=false)
     */
    private $status;
 
    /**
     * @var \TrackedObject
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     * @ORM\OneToOne(targetEntity="Gdp\Entity\TrackedObject")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id", referencedColumnName="id")
     * })
     */
    private $id;
 
 
    /**
     * Set code
     *
     * @param string $code
     * @return LocalizedValue
     */
    public function setCode($code)
    {
        $this->code = $code;
 
        return $this;
    }
 
    /**
     * Get code
     *
     * @return string 
     */
    public function getCode()
    {
        return $this->code;
    }
 
    /**
     * Set status
     *
     * @param integer $status
     * @return LocalizedValue
     */
    public function setStatus($status)
    {
        $this->status = $status;
 
        return $this;
    }
 
    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }
 
    /**
     * Set id
     *
     * @param \TrackedObject $id
     * @return LocalizedValue
     */
    public function setId(\TrackedObject $id)
    {
        $this->id = $id;
 
        return $this;
    }
 
    /**
     * Get id
     *
     * @return \TrackedObject 
     */
    public function getId()
    {
        return $this->id;
    }
}
- SystemValue
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @version    SVN:$Id: SystemValue.php 2 2013-02-13 10:44:11Z 16660 $
 * @author     16660
 */
namespace Gdp\Entity\TrackedObject\LocalizedValue;
 
use Gdp\Entity\TrackedObject\LocalizedValue;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * SystemValue
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @author     16660
 * @version    Release:1.0
 * 
 * @ORM\Table(name="system_value")
 * @ORM\Entity
 * 
 */
class SystemValue extends LocalizedValue
{
    /**
     * @var integer
     *
     * @ORM\Column(name="order", type="integer", nullable=false)
     */
    private $order;
 
    /**
     * @var \LocalizedValue
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     * @ORM\OneToOne(targetEntity="Gdp\Entity\TrackedObject\LocalizedValue")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id", referencedColumnName="id")
     * })
     */
    private $id;
 
 
    /**
     * @var \LocalizedValue
     *
     * @ORM\ManyToOne(targetEntity="Gdp\Entity\TrackedObject\LocalizedValue")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="comment_id", referencedColumnName="id")
     * })
     */
    private $comment;
 
    /**
     * Constructor
     */
    public function __construct()
    {
    }
 
    /**
     * Set order
     *
     * @param integer $order
     * @return SystemValue
     */
    public function setOrder($order)
    {
        $this->order = $order;
 
        return $this;
    }
 
    /**
     * Get order
     *
     * @return integer 
     */
    public function getOrder()
    {
        return $this->order;
    }
 
    /**
     * Set id
     *
     * @param \LocalizedValue $id
     * @return SystemValue
     */
    public function setId(\LocalizedValue $id)
    {
        $this->id = $id;
 
        return $this;
    }
 
    /**
     * Get id
     *
     * @return \LocalizedValue 
     */
    public function getId()
    {
        return $this->id;
    }
 
    /**
     * Set comment
     *
     * @param \LocalizedValue $comment
     * @return SystemValue
     */
    public function setComment(\LocalizedValue $comment = null)
    {
        $this->comment = $comment;
 
        return $this;
    }
 
    /**
     * Get comment
     *
     * @return \LocalizedValue 
     */
    public function getComment()
    {
        return $this->comment;
    }
}
- Locale
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @version    SVN:$Id: Locale.php 2 2013-02-13 10:44:11Z 16660 $
 * @author     16660
 */
namespace Gdp\Entity\TrackedObject\LocalizedValue\SystemValue;
 
use Gdp\Entity\TrackedObject\LocalizedValue\SystemValue;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * SystemValue
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @author     16660
 * @version    Release:1.0
 * 
 * @ORM\Table(name="system_value")
 * @ORM\Entity
 */
class Locale extends SystemValue
{
    /**
     * Constructor
     */
    public function __construct()
    {
    }
}
- Translation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @version    SVN:$Id$
 * @author     16660
 */
namespace Gdp\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * Translation
 * 
 * @category   Gdp
 * @package    Gdp_Entity
 * @author     16660
 * @version    Release:1.0
 * 
 * 
 * @ORM\Table(name="translation")
 * @ORM\Entity(repositoryClass="Gdp\Repository\Translation")
 * @ORM\HasLifecycleCallbacks
 */
class Translation
{
    /**
     * @var string
     *
     * @ORM\Column(name="value", type="text", nullable=true)
     */
    private $value;
 
    /**
     * @var \LocalizedValue
     *
     * @ORM\ManyToOne(targetEntity="Gdp\Entity\TrackedObject\LocalizedValue")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="localized_value_id", referencedColumnName="id")
     * })
     */
    private $localizedValue;
 
    /**
     * @var \SystemValue
     *
     * @ORM\ManyToOne(targetEntity="Gdp\Entity\TrackedObject\LocalizedValue\SystemValue")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="locale_id", referencedColumnName="id")
     * })
     */
    private $locale;
 
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
 
 
    /**
     * Set value
     *
     * @param string $value
     * @return Translation
     */
    public function setValue($value)
    {
        $this->value = $value;
 
        return $this;
    }
 
    /**
     * Get value
     *
     * @return string 
     */
    public function getValue()
    {
        return $this->value;
    }
 
    /**
     * Set localizedValue
     *
     * @param \LocalizedValue $localizedValue
     * @return Translation
     */
    public function setLocalizedValue(\LocalizedValue $localizedValue = null)
    {
        $this->localizedValue = $localizedValue;
 
        return $this;
    }
 
    /**
     * Get localizedValue
     *
     * @return \LocalizedValue 
     */
    public function getLocalizedValue()
    {
        return $this->localizedValue;
    }
 
    /**
     * Set locale
     *
     * @param \SystemValue $locale
     * @return Translation
     */
    public function setLocale(\SystemValue $locale = null)
    {
        $this->locale = $locale;
 
        return $this;
    }
 
    /**
     * Get locale
     *
     * @return \SystemValue 
     */
    public function getLocale()
    {
        return $this->locale;
    }
 
    /**
     * Set id
     *
     * @param \TrackedObject $id
     * @return Translation
     */
    public function setId(\TrackedObject $id)
    {
        $this->id = $id;
 
        return $this;
    }
 
    /**
     * Get id
     *
     * @return \TrackedObject 
     */
    public function getId()
    {
        return $this->id;
    }
}
- Repositories :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
/**
 * PHP version 5.3
 * 
 * @category   Gdp
 * @package    Gdp_Repository
 * @version    SVN:$Id$
 * @author     16660
 */
namespace Gdp\Repository;
 
use Doctrine\ORM\Query\ResultSetMapping;
 
use Doctrine\ORM\EntityRepository;
use Doctrine\DBAL\Query;
use Gdp\Entity;
 
/**
 * Translation repository
 * 
 * @category   Gdp
 * @package    Gdp_Repository
 * @author     16660
 * @version    Release:1.0
 */
class Translation extends EntityRepository
{
	/**
	 * Get application translation
	 * @return array
	 */
	public function getTranslations(){
		$query= $this -> _em->createQuery("SELECT t.value FROM \Gdp\Entity\Translation t JOIN t.locale l WHERE t.value LIKE '%F%'");
		$translations = $query->getResult();
		\Zend_Debug::dump($translations);
		exit;
	}
}

Bref, je fais ca :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
$repository = $this -> _em->getRepository('\Gdp\Entity\Translation');
$test = $repository -> findOneBy(array('id' => 1));
Zend_Debug::dump($test);
Je récupère l'entité complète avec toutes les dépendances sans aucune erreur.

Quand je fais cela :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
$query= $this -> _em->createQuery("SELECT t.value FROM \Gdp\Entity\Translation t JOIN t.locale l WHERE t.value LIKE '%F%'");
$translations = $query->getResult();
\Zend_Debug::dump($translations);
exit;
Bah c'est un échec critique :'(
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 's1_'' in /data/www/dev/16660/gdp/php/library/Doctrine/DBAL/Connection.php:646 Stack trace: #0 /data/www/dev/16660/gdp/php/library/Doctrine/DBAL/Connection.php(646): PDO->query('SELECT t0_.valu...') #1 /data/www/dev/16660/gdp/php/library/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php(46): Doctrine\DBAL\Connection->executeQuery('SELECT t0_.valu...', Array, Array, NULL) #2 /data/www/dev/16660/gdp/php/library/Doctrine/ORM/Query.php(264): Doctrine\ORM\Query\Exec\SingleSelectExecutor->execute(Object(Doctrine\DBAL\Connection), Array, Array) #3 /data/www/dev/16660/gdp/php/library/Doctrine/ORM/AbstractQuery.php(737): Doctrine\ORM\Query->_doExecute() #4 /data/www/dev/16660/gdp/php/library/Doctrine/ORM/AbstractQuery.php(538): Doctrine\ORM\AbstractQuery->execute(NULL, 1) #5 /data/www/dev/16660/gdp/php/library/Gdp/Repository/Translation.php(34): Doctrine\ORM\AbstractQuery->getResult() #6 /data in /data/www/dev/16660/gdp/php/library/Doctrine/DBAL/DBALException.php on line 47
Et la requête posant problème :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
    t0_.value AS value0
FROM
    translation t0_
        INNER JOIN
    system_value s1_ ON t0_.locale_id = s1_.id
        LEFT JOIN
    localized_value l2_ ON s1_.id = l2_.id
        LEFT JOIN
    tracked_object t3_ ON s1_.id = t3_.id
        LEFT JOIN
    system_value s1_ ON s1_.id = s1_.id
WHERE
    t0_.value LIKE '%F%'

Au final, j'ai deux fois la jointure sur system_value, comme si l'entité Locale est jointe correctement mais qu'à la fin, vis à vis de l'entité systemValue il fait quand même une jointure.
J'ai essayé le mapping single table pour cette entité mais .... échec (il sembelrait que le mix SINGLE_TABLE et CLASS TABLE soit impossible...)

Quelqu'un aurait-il une idée ? En sachant derrière que certaines entitées qui héritent de system_value peuvent elles avoir une table de jointure.

L'idée serait peut-être de créer deux entités distinctes permettant de gérer l'un des deux cas mais là on arrive à du lourd en terme de code.... et gérer une table locale juste avec un id en colonne est quelque peu incohérent....

Merci d'avance pour vos réponses.