[DDC-3343] `PersistentCollection::removeElement` schedules an entity for deletion when relationship is EXTRA_LAZY, with `orphanRemoval` false. Created: 09/Oct/14  Updated: 13/Oct/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2, 2.3, 2.4
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Andrea Sprega Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, orm


 Description   

Given the following entity for which I only report the relevant association:

class Group
{
    /**
     * @ORM\OneToMany(targetEntity="User", mappedBy="group", fetch="EXTRA_LAZY")
     */
    protected $users;
    //...
}

and its inverse

class User
{
    /**
     * @ORM\ManyToOne(targetEntity="Group", inversedBy="users")
     * @ORM\JoinColumn(name="group_id", onDelete="SET NULL")
     */
    protected $group;
    //...
}

I experience a weird issue when, inside Group, I call $this->users->removeElement($user): Doctrine schedules the $user entity for deletion, no matter what (it doesn't check for the orphanRemoval attribute). Also, even re-adding the entity to a new Group before the flush() occurs doesn't prevent it from being deleted.

I believe this is a bug, since I do not see any special mention of this behavior in the documentation for extra lazy associations:
http://doctrine-orm.readthedocs.org/en/latest/tutorials/extra-lazy-associations.html.

The workaround for me has been to remove fetch="EXTRA_LAZY" from the relationship.

After digging a little bit into the source code, this seems to be the commit (and the line) that introduced this behavior:

https://github.com/doctrine/doctrine2/commit/356f5874bf81ca4e37681c233e24cc84d16e7a39#diff-108586f774fc8acb02163ed709e05e86R403

I also found this on Google:

https://groups.google.com/forum/#!topic/doctrine-user/cx_yBuoqiAE

which basically didn't help much, except for suggesting that it should be a feature when there is an orphanRemoval and/or a cascade operation in place (and that makes perfectly sense).

I set this to "critical" since (as it occurred to me) it can lead to irrecoverable data loss.

Is this effectively a bug?






[DDC-2954] Paginator loses items Created: 05/Feb/14  Updated: 12/Feb/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.4, 2.4.1
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Mariusz Jaskółka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Pagination, Paginator
Environment:

Linux and Windows, PHP 5, Oracle(OCI8)


Attachments: File LimitSubqueryOutputWalker.php     File LimitSubqueryOutputWalker_bugfix.php    

 Description   

Sometimes when when I use Paginator (Doctrine\ORM\Tools\Pagination\Paginator)

  • with query contains orderBy
  • with $fetchJoinCollection = true
  • lot of joins with toMany associations

there are too few items in result (no, it is not the end of list). There two situations:
1. I have four items on page 1 and two items on page 2 (pageLimit is 5). It is no so bad
2. I have four items on page 1 and there is no page 2 (while there should be 5 all items). This is very bad because I lose one item.

------------------------------------------------------------------
EDIT:
In function Paginator::getIterator there is variable $ids. In my situation it contains five numbers [34,26,34,15,12]. There is duplicated value 34 but ids of top-level entities should be distinct (as far as we do not use CROSS JOIN, or maybe I am wrong).

The Paginator::count function works correctly, it does not count duplicated values twice.

Statement that gets $ids is like following:
SELECT a.* FROM (SELECT DISTINCT ID2, BEGINTIME70 FROM (...) dctrn_result ORDER BY BEGINTIME70 DESC) a WHERE ROWNUM <= 5

------------------------------------------------------------------
EDIT 2 - Bugfix description:
The result items of the query is not unique because of
"SELECT DISTINCT col_with_id, order_by_column (...) ORDER BY order_by_column".
If we had items like following:
(1,A)
(1,B)
(1,B)
(2,C)

After DISTINCT operation the result would be:
(1,A)
(1,B)
(2,C)

But we want to have unique firs column, not pairs. That's why we should do "ORDER BY" before "DISTINCT" - not in the same time.
Please confirm if the solution is correct.



 Comments   
Comment by Marco Pivetta [ 05/Feb/14 ]

Mariusz Jaskółka this needs more details

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

OK, I will try to find out where the problem is.

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

I have edited description, maybe additional information will help.

Comment by Mariusz Jaskółka [ 07/Feb/14 ]

I send the bugfix in attachment. I will describe it soon.

Comment by Mariusz Jaskółka [ 07/Feb/14 ]

Bugfix version 2 - previously I did not notice that oracle loses order after DISTINCT operation. Thus I used GROUP BY.

Comment by Mariusz Jaskółka [ 11/Feb/14 ]

I do not know if I can change status of this issue from "Awaiting Feedback". I can not see such option





[DDC-2879] Persisting collections with Composite Primary Keys composed of 2 Foreign Keys and one metadata field Created: 31/Dec/13  Updated: 07/Jan/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Dylan Johnson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: composite, identity, mapping, orm, postgresql
Environment:

Ubuntu 13.04 and PostgresSQL 9.1.0 on Vagrant Virtual Machine running an application with Symfony2 backend and JavaScript client



 Description   

SYNOPSIS

Bug prevents persisting a collection of entities in a join table with a Composite Primary
Key made up of 2 Foreign Keys and one metadata field. From these mapping instructions:
http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-3-join-table-with-metadata

ISSUE DETAILS

SUCCESS: When FOREIGN KEY 1 is the same across items in a collection to be persisted, and FOREIGN KEY 2 is greater than FOREIGN KEY 2 in any existing PRIMARY KEY, the entity and collection are persisted correctly

    • Example: GPA "add val below" exists and has assessment value
      {"grade_point_average_id":1,"assessment_id":1,"value":4}

      We will try to add a new assessment value where assessment_id > that of any existing assessment value for GPA "add val below"

    • Request Payload:
      {"name":"Add Val Below","courses":[],"assessmentValues":[{"assessment":1,"value":4},{"assessment":3,"value":2}]}
    • Debug Log:
      [2014-01-07 11:48:01] app.INFO: START GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL BELOW] [] []
      [2014-01-07 11:48:01] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 4 [] []
      [2014-01-07 11:48:01] app.INFO:         MANAGED? 1 [] []
      [2014-01-07 11:48:01] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:48:01] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 3 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 2 [] []
      [2014-01-07 11:48:01] app.INFO:         MANAGED?  [] []
      [2014-01-07 11:48:01] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 3 [] []
      [2014-01-07 11:48:01] app.INFO: END GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL BELOW] [] []
      [2014-01-07 11:48:01] doctrine.DEBUG: "START TRANSACTION" [] []
      [2014-01-07 11:48:01] doctrine.DEBUG: INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?) {"1":2,"2":"1","3":"3"} []
      [2014-01-07 11:48:01] doctrine.DEBUG: UPDATE gpa_assessment_value SET point_value = ? WHERE grade_point_average_id = ? AND assessment_id = ? [4,1,1] []
      [2014-01-07 11:48:01] doctrine.DEBUG: "COMMIT" [] []

FAILURE: When FOREIGN KEY 1 is the same across items in a collection, and FOREIGN KEY 2 is less than any existing FOREIGN KEY 2, the unit of work tries to INSERT existing entity and does not operate on new entity. The EntityManager thinks it contains() the new entity, but not the old one

    • Example: GPA "add val above" exists and has assessment value
      {"assessment":3,"value":2}

      We will try to add a new assessment value where assessment_id < that of any existing assessment value for GPA "add val above"

    • Request Payload:
      {"name":"Add Val Above","courses":[],"assessmentValues":[{"assessment":1,"value":4},{"assessment":3,"value":2}]}
    • Debug log:
      [2014-01-07 11:47:09] app.INFO: START GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL ABOVE] [] []
      [2014-01-07 11:47:09] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 1 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 1 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 4 [] []
      [2014-01-07 11:47:09] app.INFO:         MANAGED? 1 [] []
      [2014-01-07 11:47:09] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:47:09] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 3 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         MANAGED?  [] []
      [2014-01-07 11:47:09] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 3 [] []
      [2014-01-07 11:47:09] app.INFO: END GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL ABOVE] [] []
      [2014-01-07 11:47:09] doctrine.DEBUG: "START TRANSACTION" [] []
      [2014-01-07 11:47:09] doctrine.DEBUG: INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?) {"1":2,"2":"2","3":"3"} []
      [2014-01-07 11:47:09] doctrine.DEBUG: "ROLLBACK" [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException". [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelException". [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ExceptionListener::onKernelException". [] []
      [2014-01-07 11:47:09] request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\DBALException: "An exception occurred while executing 'INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?)' with params [2, "2", "3"]:
      
      SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "gpa_assessment_value_pkey"
      DETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists." at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php line 47 {"exception":"[object] (Doctrine\\DBAL\\DBALException: An exception occurred while executing 'INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?)' with params [2, \"2\", \"3\"]:\n\nSQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint \"gpa_assessment_value_pkey\"\nDETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists. at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:47, PDOException: SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint \"gpa_assessment_value_pkey\"\nDETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists. at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php:138)"} []
         

CODE

migration.sql
CREATE TABLE assessment
(
    id       bigserial NOT NULL,
    scale_id bigint    NOT NULL,
    title    varchar   NOT NULL,
    passing  boolean   NOT NULL,
    rank     int,

    PRIMARY KEY (id)
);

CREATE TABLE assessment_scale
(
    id   bigserial NOT NULL,
    name varchar   NOT NULL,

    PRIMARY KEY (id)
);

-- ...

CREATE TABLE grade_point_average
(
    id                         bigserial       NOT NULL,
    name                       varchar         NOT NULL,
    additional_credit_allowance numeric(4, 2),

    PRIMARY KEY (id)
);

-- ...

CREATE TABLE gpa_assessment_value
(
    grade_point_average_id bigint        NOT NULL,
    assessment_id          bigint        NOT NULL,
    point_value            numeric(4, 2) NOT NULL,

    PRIMARY KEY (assessment_id, grade_point_average_id),
    FOREIGN KEY (assessment_id) REFERENCES assessment,
    FOREIGN KEY (grade_point_average_id) REFERENCES grade_point_average
);
GradePointAverage.php
<?php
namespace LGSConnect\Model;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
//...
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use LGSConnect\Util\ConstructorArgs;
use LGSConnect\Model\GradePointAverage\AssessmentValue;
// ...

/**
 * @Entity("LGSConnect\Repository\GradePointAverageRepository")
 */
class GradePointAverage
{
    // GradePointAverage Model (owning side): a tool for evaluating a student's performance 
    // by dividing the total points earned by total credits attempted.

    use ConstructorArgs;

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     *
     * @var int
     */
    private $id;

    // ...

    /**
     * @OneToMany(targetEntity="LGSConnect\Model\GradePointAverage\AssessmentValue", mappedBy="gradePointAverage", cascade="persist")
     *
     * @var Collection
     */
    private $assessmentValues;
    
    // ...

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->assessmentValues = new ArrayCollection;
        // ...
        $this->handleArgs($args);
    }
    
    // ...
    
    /**
     * @return Collection
     */
    public function getAssessmentValues()
    {
        return $this->assessmentValues;
    }

    /**
     * @param ArrayCollection $assessmentValues
     */
    public function setAssessmentValues(ArrayCollection $assessmentValues)
    {
        $this->assessmentValues = $assessmentValues;
    }

    /**
     * @param AssessmentValue $assessmentValue
     */
    public function addAssessmentValue(AssessmentValue $assessmentValue)
    {
        $this->assessmentValues->add($assessmentValue);
    }

    /**
     * @param AssessmentValue $assessmentValue
     */
    public function removeAssessmentValue(AssessmentValue $assessmentValue)
    {
        $this->assessmentValues->removeElement($assessmentValue);
    }
    
    // ...
}
AssessmentValue.php
<?php
namespace LGSConnect\Model\GradePointAverage;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\JoinColumn;
use LGSConnect\Model\GradePointAverage;
use LGSConnect\Model\Assessment;
use LGSConnect\Util\ConstructorArgs;

/**
 * @Entity("LGSConnect\Repository\GradePointAverage\AssessmentValueRepository")
 * @Table("gpa_assessment_value")
 */
class AssessmentValue
{
    // AssessmentValue Model (inverse side): a number of points assigned 
    // to an Assessment by a Grade Point Average

    use ConstructorArgs;

    /**
     * @Id
     * @ManyToOne(targetEntity="LGSConnect\Model\GradePointAverage")
     */
    private $gradePointAverage;

    /**
     * @Id
     * @ManyToOne(targetEntity="LGSConnect\Model\Assessment")
     */
    private $assessment;

    /**
     * @Column("point_value")
     *
     * @var float
     */
    private $value;

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->handleArgs($args);
    }

    /**
     * @return GradePointAverage
     */
    public function getGradePointAverage()
    {
        return $this->gradePointAverage;
    }

    /**
     * @param GradePointAverage $gradePointAverage
     */
    public function setGradePointAverage(GradePointAverage $gradePointAverage)
    {
        $this->gradePointAverage = $gradePointAverage;
    }

    /**
     * @return Assessment
     */
    public function getAssessment()
    {
        return $this->assessment;
    }

    /**
     * @param Assessment $assessment
     */
    public function setAssessment(Assessment $assessment)
    {
        $this->assessment = $assessment;
    }

    /**
     * @return float
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param float $value
     */
    public function setValue($value)
    {
        $this->value = $value;
    }

    /**
     * @return AssessmentScale
     */
    public function getAssessmentScale()
    {
        return $this->assessment->getScale();
    }
}
Assessment.php
<?php
namespace LGSConnect\Model;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\ManyToOne;
use LGSConnect\Model\Assessment\Scale;
use LGSConnect\Util\ConstructorArgs;

/**
 * @Entity("LGSConnect\Repository\AssessmentRepository")
 */
class Assessment
{
    // Assessment (related, but unmapped): A "grade" assigned to a student 
    // for attending a course section

    use ConstructorArgs;

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     *
     * @var int
     */
    private $id;
    
    // ...

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->handleArgs($args);
    }

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    
    // ...
}
GradePointAverageRepository.php
<?php
namespace LGSConnect\Repository;

use Doctrine\ORM\EntityRepository;
// ...
use LGSConnect\Model\GradePointAverage;

class GradePointAverageRepository extends BaseRepository implements GradePointAverageRepositoryInterface
{
    // ...

    /**
     * @param GradePointAverage $gradePointAverage
     */
    public function save(GradePointAverage $gradePointAverage)
    {
        $this->getEntityManager()->persist($gradePointAverage);
        $this->getEntityManager()->flush();
    }
}
AssessmentValueRepository.php
<?php
namespace LGSConnect\Repository\GradePointAverage;

use Doctrine\ORM\EntityRepository;
use LGSConnect\Model\GradePointAverage\AssessmentValue;

class AssessmentValueRepository extends EntityRepository
{
    /**
     * @param AssessmentValue $assessmentValue
     */
    public function save(AssessmentValue $assessmentValue)
    {
        $this->getEntityManager()->persist($assessmentValue);
        $this->getEntityManager()->flush();
    }
}
GradePointAverageManager.php
<?php
namespace LGSConnect\Manager;

use InvalidArgumentException;
use Symfony\Component\Validator\ValidatorInterface;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\SecurityExtraBundle\Annotation\PreAuthorize;
use Knp\Component\Pager\Pagination\PaginationInterface;
use LGSConnect\Repository\GradePointAverageRepository;
use LGSConnect\PaginationFactory\GradePointAveragePaginationFactoryInterface;
use LGSConnect\Model\GradePointAverage;

/**
 * @Service("grade_point_average_manager")
 */
class GradePointAverageManager
{
    /**
     * @var GradePointAverageRepository
     */
    private $gradePointAverageRepository;

    /**
     * @var GradePointAveragePaginationFactoryInterface
     */
    private $gradePointAveragePaginationFactory;

    /**
     * @var ValidatorInterface
     */
    private $validator;

    /**
     * @InjectParams
     *
     * @param GradePointAverageRepository $gradePointAverageRepository
     * @param GradePointAveragePaginationFactoryInterface $gradePointAveragePaginationFactory
     * @param ValidatorInterface $validator
     */
    public function __construct(
        GradePointAverageRepository $gradePointAverageRepository,
        GradePointAveragePaginationFactoryInterface $gradePointAveragePaginationFactory,
        ValidatorInterface $validator
    )
    {
        $this->gradePointAverageRepository = $gradePointAverageRepository;
        $this->gradePointAveragePaginationFactory = $gradePointAveragePaginationFactory;
        $this->validator = $validator;
    }

    /**
     * @PreAuthorize("isAllowedToManageTheGradePointAverage(#gradePointAverage)")
     * @param GradePointAverage $gradePointAverage
     * @throws InvalidArgumentException
     */
    public function save(GradePointAverage $gradePointAverage)
    {
        $violationList = $this->validator->validate($gradePointAverage);
        if ($violationList->count()) {
            throw new InvalidArgumentException;
        }

        $this->gradePointAverageRepository->save($gradePointAverage);
    }
}
GradePointAverageController.php
<?php
namespace LGSConnect\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Doctrine\Common\Collections\ArrayCollection;
use FOS\RestBundle\View\View;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\SecurityExtraBundle\Annotation\PreAuthorize;
use Knp\Component\Pager\Pagination\PaginationInterface;
use LGSConnect\Manager\GradePointAverageManager;
use LGSConnect\Model\GradePointAverage;
use LGSConnect\Model\GradePointAverage\AssessmentValue;

/**
 * @Service("grade_point_average_controller", parent="lgs.controller.abstract")
 * @Route("/gpa", service="grade_point_average_controller")
 */
class GradePointAverageController extends BaseController
{
    /**
     * @var GradePointAverageManager
     */
    private $gradePointAverageManager;

    private $logger;

    /**
     * @InjectParams
     *
     * @param GradePointAverageManager $gradePointAverageManager
     * @param LoggerInterface $logger
     */
    public function __construct(GradePointAverageManager $gradePointAverageManager, LoggerInterface $logger)
    {
        $this->gradePointAverageManager = $gradePointAverageManager;
        $this->logger = $logger;
    }
    
    // ...

    /**
     * @Route("/{id}", name="gpa.edit", requirements={"id" = "\d+"})
     * @Method("PUT")
     *
     * @param Request $request
     * @param GradePointAverage $gpa
     * @return View
     */
    public function editAction(Request $request, GradePointAverage $gpa)
    {
        $form = $this->formFactory->createNamed(null, 'gpa', $gpa, [
            'method' => 'PUT',
        ]);
        $form->handleRequest($request);

        foreach ($gpa->getAssessmentValues() as $av) {
            $this->logger->info('GPA ID PREVALIDATE IN CONTROLLER:'.$gpa->getId());
            $this->logger->info('PREVALIDATE IN CONTROLLER ASSESSMENT VAL ASSESSMENT ID:'.$av->getAssessment()->getId());
            $this->logger->info('PREVALIDATE IN CONTROLLER ASSESSMENT VAL POINTS:'.$av->getValue());
        }

        /*
        // try reversing the order of the collection to see if that helps
        $assessmentVals = $gpa->getAssessmentValues()->toArray();
        $reversed = array_reverse($assessmentVals);
        $reversedColl = new ArrayCollection($reversed);
        $gpa->setAssessmentValues($reversedColl);
        */

        if ($form->isValid()) {
            foreach ($gpa->getAssessmentValues() as $av) {
                $this->logger->info('GPA ID PRESAVE IN CONTROLLER:'.$gpa->getId());
                $this->logger->info('PRESAVE IN CONTROLLER ASSESSMENT VAL ASSESSMENT ID:'.$av->getAssessment()->getId());
                $this->logger->info('PRESAVE IN CONTROLLER ASSESSMENT VAL POINTS:'.$av->getValue());
            }
            $this->gradePointAverageManager->save($gpa);

            return new View($gpa, 204);
        }

        return new View($form);
    }

    // ...
}
GradePointAverageType.php
<?php
namespace LGSConnect\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use JMS\DiExtraBundle\Annotation\FormType;

/**
 * @FormType
 */
class GradePointAverageType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('courses', 'entity', [
                'class' => 'Model:Course',
                'multiple' => true
            ])
            ->add('assessmentValues', 'collection', [
                'type' => 'gpa_assessment_value',
                'allow_add' => true,
                'by_reference' => false,
            ])
        ;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'gpa';
    }
}
AssessmentValueType.php
<?php
namespace LGSConnect\Form\Type\GradePointAverage;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use JMS\DiExtraBundle\Annotation\FormType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
 * @FormType("gpa_assessment_value")
 */
class AssessmentValueType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('assessment', 'entity', [
                'class' => 'Model:Assessment',
            ])
            ->add('value', 'number', [
                'precision' => 2,
            ])
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'LGSConnect\Model\GradePointAverage\AssessmentValue',
        ]);
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'gpa_assessment_value';
    }
}





[DDC-2870] Doctrine error when using SUM(a.id=1) as `ìdentifier`: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '=' Created: 22/Dec/13  Updated: 06/Jan/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Maxim Geerinck Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql
Environment:

Symfony2 bundle



 Description   

Doctrine error when using SUM(a.id=1) as `ìdentifier`: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='

I am trying to execute a query in doctrine that contains something like this

SUM(a.id = 1) as `1`
for some reasons it always gives me the following error:

[Syntax Error] line 0, col 15: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='
This is the code i am using

$result = $em->getRepository('MyBundle:PlayerAction')
->createQueryBuilder('pa')
->select(array(
'SUM(a.id=1) as `1`,
SUM(a.id=2) as `2`,
SUM(a.id=3) as `3`,
p.playerName,
pa.timestamp'
))
->innerJoin('pa.action', 'a')
->innerJoin('pa.player', 'p')
->where('pa.timestamp > ?1')
->groupBy('p')
->setParameter(1, time() - $time)
->orderBy('p.playerName', 'ASC');






[DDC-2746] When generating DQL query entities with "Class Table Inheritance" is a SQL generated inconsistent Created: 16/Oct/13  Updated: 18/Oct/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Hugo Henrique Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File DDC2746Test.php     File DDC2746Test_original.php    

 Description   

When I run the query DQL involving entities "Class Table Inheritance" is a SQL generated inconsistent see this gist: https://gist.github.com/hugohenrique/b322e8d998c870265177



 Comments   
Comment by Hugo Henrique [ 17/Oct/13 ]

An example of incoherent generation of SQL:
https://gist.github.com/hugohenrique/b322e8d998c870265177





[DDC-2675] WITH (NOLOCK) failing when using JOIN Created: 12/Sep/13  Updated: 31/Jan/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None
Environment:

MSSQL 2008 R2


Issue Links:
Duplicate
is duplicated by DDC-2310 Recent changes to DBAL SQL Server pla... Resolved
Reference
is referenced by DDC-2919 LockMode::NONE evaluation inconsisten... Resolved

 Description   

I ran the doctrine test suite and there are a lot of tests failing with

[SQL Server]Incorrect syntax near the keyword 'with'

List of failing test because of this issue:
2) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testUnnamedScalarResultsAreOneBased
3) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testOrderByResultVariableCollectionSize
4) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testIsNullAssociation
5) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testSelectSubselect
6) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testInSubselect
7) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testGroupByMultipleFields
8) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testUpdateAs
9) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testDeleteAs
10) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testCRUD
11) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testSelfReferencingOneToOne
12) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testSelfReferencingManyToMany
13) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testLazyLoading2
14) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testBulkUpdateIssueDDC368
15) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testBulkUpdateNonScalarParameterDDC1341
16) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testQueryForInheritedSingleValuedAssociation
17) Doctrine\Tests\ORM\Functional\Locking\OptimisticTest::testJoinedChildFailureThrowsException
18) Doctrine\Tests\ORM\Functional\Locking\OptimisticTest::testJoinedParentFailureThrowsException
19) Doctrine\Tests\ORM\Functional\OrderedJoinedTableInheritanceCollectionTest::testOrderdOneToManyCollection
20) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateSum
21) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateAvg
22) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateMin
23) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateMax
24) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateCount
25) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionAbs
26) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionConcat
27) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLength
28) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLocate
29) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLower
30) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionMod
31) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionSqrt
32) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionUpper
33) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionSubstring
34) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionTrim
35) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorAdd
36) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorSub
37) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorMultiply
38) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorDiv
39) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testConcatFunction
40) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateDiff
41) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateAdd
42) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateSub
43) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testBitOrComparison
44) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testBitAndComparison
45) Doctrine\Tests\ORM\Functional\SQLFilterTest::testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingSubEntity
46) Doctrine\Tests\ORM\Functional\SQLFilterTest::testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingRootEntity
47) Doctrine\Tests\ORM\Functional\Ticket\DDC163Test::testQueryWithOrConditionUsingTwoRelationOnSameEntity
48) Doctrine\Tests\ORM\Functional\Ticket\DDC168Test::testJoinedSubclassPersisterRequiresSpecificOrderOfMetadataReflFieldsArray
49) Doctrine\Tests\ORM\Functional\Ticket\DDC1995Test::testIssue
50) Doctrine\Tests\ORM\Functional\Ticket\DDC1995Test::testQueryCache
51) Doctrine\Tests\ORM\Functional\Ticket\DDC2090Test::testIssue
53) Doctrine\Tests\ORM\Functional\Ticket\DDC279Test::testDDC279
54) Doctrine\Tests\ORM\Functional\Ticket\DDC933Test::testLockCTIClass

One example, test 20)
Generated SQL:

SELECT SUM(c0_.salary) AS sclr0
FROM company_managers c1_
INNER JOIN company_employees c0_ ON c1_.id = c0_.id
INNER JOIN company_persons c2_ ON c1_.id = c2_.id
WITH (NOLOCK)

Solution:
Placing WITH (NOLOCK) after the table(s), instead of after ON clause. Depending on the wanted result it should be placed several times when using JOIN. See this StackOverflow Post for more information:
http://stackoverflow.com/questions/3783525/sql-server-nolock-and-joins



 Comments   
Comment by Steve Müller [ 15/Jan/14 ]

Please refer to DDC-2310 as it describes exactly the same issue.

Comment by Doctrine Bot [ 31/Jan/14 ]

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





[DDC-2631] Replacing object in a OneToOne with OrphanRemoval=true isn't working as expected Created: 23/Aug/13  Updated: 26/Nov/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Felipe Guaycuru Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

PHP 5.4



 Description   

So I have a class defined like this:

class PhoneSettings {
[...]

/**

  • @OneToOne(targetEntity="Medium", cascade= {"persist", "remove"}

    , orphanRemoval=true)

  • @JoinColumn(name="medium_id", referencedColumnName="medium_id", nullable=true, onDelete="SET NULL")
    **/
    protected $medium = null;

[...]
}
And class Medium has no reference to the class Settings.

Now suppose I have a $Settings object that is already persisted and has been correctly loaded. Also suppose that the $Settings object has a $medium (that is, $Settings->medium = $OldMedium)

Now suppose I do:

$Settings->medium = $NewMedium;
Where $NewMedium is a different Medium object.

When I persist $Settings, Doctrine does delete $OldMedium from the DB, but the problem is that it also deletes $NewMedium ...

I have tried removing onDelete="SET NULL", but then I receive a "cannot delete, constraint failed" error...






[DDC-2590] Class inheritance - left join between child and parent entities Created: 06/Aug/13  Updated: 25/Mar/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.1, 2.3.2, 2.3.3, 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Tomáš Ďuračka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, joins, orm, sql-walker


 Description   

The piece of code given under creates wrong sql to me.

Module is parent entity for BusinessModule entity. Category is joined with BusinessModule.

Module entity is only left joined to its child entity and that's the problem because it contains a field "name" used for filtering. So even if there is no module having the name, categories are still included.

I need the parent entity to be inner joined to child entity not left joined.

File doctrine2/lib/Doctrine/ORM/Query/SqlWalker.php line 353:

// If this is a joined association we must use left joins to preserve the correct result.
$sql .= isset($this->queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER ';
$qb->select('c')
->from('Category', 'c')
->join('c.module', 'm', 'WITH', 'm.name = :moduleName')
->setParameter('moduleName', $moduleName);
SELECT c0_.category_id AS category_id0, c0_.title AS title1, c0_.h1 AS h12, c0_.alias AS alias3,
c0_.insertion_fee AS insertion_fee4, c0_.description AS description5, c0_.parent_category_id AS
parent_category_id6, c0_.module_id AS module_id7 
FROM category c0_ 
INNER JOIN business_module b1_ ON c0_.module_id = b1_.module_id 
LEFT JOIN module m2_ ON b1_.module_id = m2_.module_id AND (m2_.name = ?)


 Comments   
Comment by Marek Štípek [ 06/Nov/13 ]

I am experiencing the same issue. The workarround could be to use LEFT JOIN with IS NOT NULL condition... But it also doesnt work after this commit
https://github.com/doctrine/doctrine2/commit/d9c1782a4f6d46f66e9deb2c375830f9192d4482 (i had to revert to dev-master#13c1efb240dd0af25ad0abe230df98ec895892c7)





[DDC-2449] Amazon Redshift Support Created: 15/May/13  Updated: 15/May/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: Kirill Fuchs Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Amazon Redshift



 Description   

It would be nice to get doctrine compatible with Amazon Redshift. It uses a Postgres connector but there are some differences. I'm currently facing an issue with the primary id, in Redshift the generation of an id is different from Postgres and so I'm getting errors associated with generating an id.

Here are some references that might be useful:
node-orm faced the same issue and seems like they figured it out: https://github.com/dresende/node-orm2/issues/39

Amazon Manual:
http://awsdocs.s3.amazonaws.com/redshift/latest/redshift-dg.pdf






[DDC-2387] convert-mapping not working correctly with composite primary keys/foreign keys in 2.4.0-RC1 Created: 03/Apr/13  Updated: 01/Jul/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4
Fix Version/s: 2.3.4
Security Level: All

Type: Bug Priority: Major
Reporter: Nicholas Van Dusen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 4
Labels: None
Environment:

Symfony 2.2.0, MySQL 5.1



 Description   

(Apologies if this is somehow a Symfony-specific issue)

I updated my application via Composer yesterday, and received Doctrine 2.4.0-RC1. After this update, generating entities has been problematic under certain circumstances.

Here is an example table in MySQL:

CREATE TABLE `user_email` (
  `user_id` int(10) unsigned NOT NULL COMMENT 'FK to user',
  `email` varchar(254) NOT NULL,
  `email_datasource` smallint(1) unsigned NOT NULL COMMENT 'FK to datasource_code',
  `insert_date` datetime NOT NULL,
  PRIMARY KEY (`user_id`,`email`,`email_datasource`),
  KEY `FK_UserEmail_DataSourceCode` (`email_datasource`),
  CONSTRAINT `FK_UserEmail_User` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

In Doctrine 2.3, the mapping works correctly, and you end up with a 3-part primary key, with a user property mapped to the User entity, and a datasourceCode property mapped to the DatasourceCode entity. All good.

In 2.4, the following error is given: Single id is not allowed on composite primary key in entity UserEmail.

Removing one of the foreign keys in the table (either to User or DatasourceCode) but keeping the primary key set to all 3 columns allows the mapping to work. But, if you then remove one of the columns from the primary key (say, email_datasource) it fails again.



 Comments   
Comment by Benjamin Eberlei [ 04/Apr/13 ]

Can you provide the full stack trace to the exception please?

$e->getTraceAsString();
Comment by Nicholas Van Dusen [ 11/Apr/13 ]

Benjamin, I'm not sure how to get the trace for you, since I'm running from inside the Symfony2 doctrine:mapping:import command line item.

Comment by Christophe Coevoet [ 11/Apr/13 ]

Use the --verbose option when running the command

Comment by Nicholas Van Dusen [ 11/Apr/13 ]

I was able to get a trace for you:

#0 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php(1571): Doctrine\ORM\Mapping\MappingException::singleIdNotAllowedOnCompositePrimaryKey('UserEmail')
#1 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(422): Doctrine\ORM\Mapping\ClassMetadataInfo->getSingleIdentifierFieldName()
#2 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(136): Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping(Object(Doctrine\ORM\Mapping\ClassMetadata))
#3 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(302): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL, false, Array)
#4 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(212): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('UserEmail')
#5 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(112): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('UserEmail')
#6 /var/www/html/voxrepublic/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php(108): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata()
#7 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(240): Doctrine\Bundle\DoctrineBundle\Command\ImportMappingDoctrineCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(195): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(78): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(106): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/html/voxrepublic/app/console(22): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#12 {main}
Comment by Benjamin Eberlei [ 14/Apr/13 ]

The problem is that Doctrine seems to detect that you only have on id field on this entity and then a new function of 2.4 throws this error. I will try to reproduce this with your table. Until then could you show me the var_dump() of the $class variable in Doctrine\ORM\ClassMetadataFactory#completeIdGeneratorMapping()? This would help very much already.

Comment by Maximilian Beck [ 15/Apr/13 ]

I have the same error when using "doctrine:mapping:import"

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`step` (

  `recipe_id` INT NOT NULL ,

  `step_number` INT NOT NULL ,

  `description` TEXT NULL ,

  `timer` INT NULL ,

  `image` VARCHAR(100) NULL ,

  PRIMARY KEY (`recipe_id`, `step_number`) ,

  INDEX `recipe_id_idx` (`recipe_id` ASC) ,

  INDEX `step_number` (`step_number` ASC) ,

  CONSTRAINT `step_recipe_id`

    FOREIGN KEY (`recipe_id` )

    REFERENCES `dev_Recipe`.`recipe` (`recipe_id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION)

ENGINE = InnoDB;
Exception trace:
 () at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php:258
 Doctrine\ORM\Mapping\MappingException::singleIdNotAllowedOnCompositePrimaryKey() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php:1571
 Doctrine\ORM\Mapping\ClassMetadataInfo->getSingleIdentifierFieldName() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php:422
 Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php:136
 Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:302
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:212
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:112
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand.php:126
 Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand->execute() at \htdocs\SF2\vendor\doctrine\doctrine-bundle\Doctrine\Bundle\DoctrineBundle\Command\Proxy\ConvertMappingDoctrineCommand.php:59
 Doctrine\Bundle\DoctrineBundle\Command\Proxy\ConvertMappingDoctrineCommand->execute() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Command\Command.php:240
 Symfony\Component\Console\Command\Command->run() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:193
 Symfony\Component\Console\Application->doRun() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.php:78
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:106
 Symfony\Component\Console\Application->run() at \htdocs\SF2\app\console:22

"var_dump($class);" returns:

object(Doctrine\ORM\Mapping\ClassMetadata)#470 (36) {
  ["name"]=>
  string(10) "Ingredient"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(10) "Ingredient"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(12) "ingredientId"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(4) {
    ["ingredientId"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(12) "ingredientId"
      ["columnName"]=>
      string(13) "ingredient_id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["color"]=>
    array(5) {
      ["fieldName"]=>
      string(5) "color"
      ["columnName"]=>
      string(5) "color"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["img"]=>
    array(6) {
      ["fieldName"]=>
      string(3) "img"
      ["columnName"]=>
      string(3) "img"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(4) {
    ["ingredient_id"]=>
    string(12) "ingredientId"
    ["name"]=>
    string(4) "name"
    ["color"]=>
    string(5) "color"
    ["img"]=>
    string(3) "img"
  }
  ["columnNames"]=>
  array(4) {
    ["ingredientId"]=>
    string(13) "ingredient_id"
    ["name"]=>
    string(4) "name"
    ["color"]=>
    string(5) "color"
    ["img"]=>
    string(3) "img"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(10) "ingredient"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(1) {
    ["ingredientCategory"]=>
    array(15) {
      ["fieldName"]=>
      string(18) "ingredientCategory"
      ["targetEntity"]=>
      string(18) "IngredientCategory"
      ["mappedBy"]=>
      string(10) "ingredient"
      ["type"]=>
      int(8)
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(false)
      ["sourceEntity"]=>
      string(10) "Ingredient"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#472 (36) {
  ["name"]=>
  string(18) "IngredientCategory"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(18) "IngredientCategory"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(2) "id"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["id"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(2) "id"
      ["columnName"]=>
      string(2) "id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(255)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(19) "ingredient_category"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["ingredient"]=>
    array(19) {
      ["fieldName"]=>
      string(10) "ingredient"
      ["targetEntity"]=>
      string(10) "Ingredient"
      ["inversedBy"]=>
      string(18) "ingredientCategory"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(30) "ingredient_category_ingredient"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(22) "ingredient_category_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(13) "ingredient_id"
            ["referencedColumnName"]=>
            string(13) "ingredient_id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(18) "IngredientCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(22) "ingredient_category_id"
        [1]=>
        string(13) "ingredient_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["ingredient_category_id"]=>
        string(2) "id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["ingredient_id"]=>
        string(13) "ingredient_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
    ["parent"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "parent"
      ["targetEntity"]=>
      string(18) "IngredientCategory"
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "parent_id"
          ["referencedColumnName"]=>
          string(2) "id"
        }
      }
      ["type"]=>
      int(2)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(18) "IngredientCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["parent_id"]=>
        string(2) "id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["parent_id"]=>
        string(9) "parent_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["id"]=>
        string(9) "parent_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#474 (36) {
  ["name"]=>
  string(6) "Recipe"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(6) "Recipe"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(8) "recipeId"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["recipeId"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(8) "recipeId"
      ["columnName"]=>
      string(9) "recipe_id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(255)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["recipe_id"]=>
    string(8) "recipeId"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["recipeId"]=>
    string(9) "recipe_id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(6) "recipe"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["recipeCategory"]=>
    array(15) {
      ["fieldName"]=>
      string(14) "recipeCategory"
      ["targetEntity"]=>
      string(14) "RecipeCategory"
      ["mappedBy"]=>
      string(6) "recipe"
      ["type"]=>
      int(8)
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(false)
      ["sourceEntity"]=>
      string(6) "Recipe"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["orphanRemoval"]=>
      bool(false)
    }
    ["users"]=>
    array(19) {
      ["fieldName"]=>
      string(5) "users"
      ["targetEntity"]=>
      string(5) "Users"
      ["inversedBy"]=>
      string(12) "recipeRecipe"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(13) "users_recipes"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(16) "recipe_recipe_id"
            ["referencedColumnName"]=>
            string(9) "recipe_id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(8) "users_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(6) "Recipe"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(16) "recipe_recipe_id"
        [1]=>
        string(8) "users_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["recipe_recipe_id"]=>
        string(9) "recipe_id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["users_id"]=>
        string(2) "id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#476 (36) {
  ["name"]=>
  string(14) "RecipeCategory"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(14) "RecipeCategory"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(2) "id"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["id"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(2) "id"
      ["columnName"]=>
      string(2) "id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(6) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(15) "recipe_category"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["recipe"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "recipe"
      ["targetEntity"]=>
      string(6) "Recipe"
      ["inversedBy"]=>
      string(14) "recipeCategory"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(22) "recipe_category_recipe"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(18) "recipe_category_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(9) "recipe_id"
            ["referencedColumnName"]=>
            string(9) "recipe_id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(14) "RecipeCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(18) "recipe_category_id"
        [1]=>
        string(9) "recipe_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["recipe_category_id"]=>
        string(2) "id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
    ["parent"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "parent"
      ["targetEntity"]=>
      string(14) "RecipeCategory"
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "parent_id"
          ["referencedColumnName"]=>
          string(2) "id"
        }
      }
      ["type"]=>
      int(2)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(14) "RecipeCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["parent_id"]=>
        string(2) "id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["parent_id"]=>
        string(9) "parent_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["id"]=>
        string(9) "parent_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#478 (36) {
  ["name"]=>
  string(4) "Step"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(4) "Step"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(2) {
    [0]=>
    string(10) "stepNumber"
    [1]=>
    string(6) "recipe"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(4) {
    ["stepNumber"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(10) "stepNumber"
      ["columnName"]=>
      string(11) "step_number"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
    ["timer"]=>
    array(5) {
      ["fieldName"]=>
      string(5) "timer"
      ["columnName"]=>
      string(5) "timer"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
    ["image"]=>
    array(6) {
      ["fieldName"]=>
      string(5) "image"
      ["columnName"]=>
      string(5) "image"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(100)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(4) {
    ["step_number"]=>
    string(10) "stepNumber"
    ["description"]=>
    string(11) "description"
    ["timer"]=>
    string(5) "timer"
    ["image"]=>
    string(5) "image"
  }
  ["columnNames"]=>
  array(4) {
    ["stepNumber"]=>
    string(11) "step_number"
    ["description"]=>
    string(11) "description"
    ["timer"]=>
    string(5) "timer"
    ["image"]=>
    string(5) "image"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(4) "step"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(1) {
    ["recipe"]=>
    array(20) {
      ["fieldName"]=>
      string(6) "recipe"
      ["targetEntity"]=>
      string(6) "Recipe"
      ["id"]=>
      bool(true)
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "recipe_id"
          ["referencedColumnName"]=>
          string(9) "recipe_id"
        }
      }
      ["type"]=>
      int(1)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(4) "Step"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(true)
  ["containsForeignIdentifier"]=>
  bool(true)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
Comment by Benjamin Eberlei [ 09/May/13 ]

Fixed and merged back to 2.3

Comment by Nicholas Van Dusen [ 29/May/13 ]

I tested this again using 2.3.4 (the version which contains this fix) and it is still occurring. Attempting to import mapping for a table with 2 foreign keys in the primary key results in the error "Database does not have any mapping information." Adding a third column on the primary key "fixes" the issue.

Currently our developers are being asked to add a fake third part to the key to work around the issue, then delete that key once they get into the entity class. This is a bit tedious and I'd love to see a fix!

Comment by Nicholas Van Dusen [ 29/May/13 ]

Issue still present in 2.3.4 and 2.4.0-RC1

Comment by Guillermo [ 11/Jun/13 ]

The database engine I use is PostgreSQL. I'm having problems when mapping entities with composite primary keys in other tables.

CREATE TABLE public.establecimiento
    (
      id_establecimiento integer NOT NULL,
      establecimiento character varying(100) NOT NULL,
      CONSTRAINT pk_establecimiento PRIMARY KEY (id_establecimiento )
    )
    WITH (
      OIDS=FALSE
    );
    CREATE TABLE public.establecimiento_sec
    (
      id_establecimiento_sec integer NOT NULL,
      id_establecimiento integer NOT NULL,
      det_seccion character varying(40) NOT NULL,
      plano character varying(100),
      sector_ingreso character varying(254),
      sponsor_imagen_sec character varying(96000),
      CONSTRAINT pk_establecimientos_sec PRIMARY KEY (id_establecimiento_sec , id_establecimiento ),
      CONSTRAINT fk_establec_reference_establec FOREIGN KEY (id_establecimiento)
          REFERENCES public.establecimiento (id_establecimiento) MATCH SIMPLE
          ON UPDATE RESTRICT ON DELETE RESTRICT
    )
    WITH (
      OIDS=TRUE
    );
    CREATE TABLE public.establecimiento_sec_plano
    (
      id_establecimiento_sec_plano integer NOT NULL,
      id_establecimiento_sec integer NOT NULL,
      id_establecimiento integer NOT NULL,
      det_plano character varying(512),
      cantidad integer NOT NULL,
      precio double precision,
      insert_charge double precision DEFAULT 0,
      descr character varying(254),
      CONSTRAINT pk_establecimiento_sec_plano PRIMARY KEY (id_establecimiento_sec_plano , id_establecimiento_sec , id_establecimiento ),
      CONSTRAINT fk_establecimiento_sec FOREIGN KEY (id_establecimiento, id_establecimiento_sec)
          REFERENCES public.establecimiento_sec (id_establecimiento, id_establecimiento_sec) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE CASCADE
    )
    WITH (
      OIDS=FALSE
    );

Defining the entity establecimientoSecPlano, $establecimientoSec variable containing the keys $establecimiento and $id_establecimiento_sec

//Entity/EstablecimientosSecPlano

/**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Ticketway\PruebaBundle\Entity\EstablecimientosSec")
     * @ORM\JoinColumns(
     *      @ORM\JoinColumn(name="id_establecimiento_sec", referencedColumnName="id_establecimiento_sec"),
     *      @ORM\JoinColumn(name="id_establecimiento", referencedColumnName="id_establecimiento")) 
     */
    private $establecimientoSec;

//Entity/EstablecimientosSec

/**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Ticketway\PruebaBundle\Entity\Establecimientos")
     * @ORM\JoinColumn(name="id_establecimiento", referencedColumnName="id_establecimiento") 
     */
    private $establecimiento;

When executing the command doctrine: mapping: import I get the following error

[Doctrine\ORM\Mapping\MappingException]
It is not possible to map entity 'EstablecimientoSec' with a composite primary key as part of the
primary key of another entity 'EstablecimientoSecPlano#idEstablecimiento'.

Comment by Sam Van der Borght [ 28/Jun/13 ]

We are having the same problem as Guillermo. Any idea on how to fix this issue?
Does anybody know why this problem occurs? I have been looking in the code but havent had much success.

Comment by Diego Antunes [ 01/Jul/13 ]

Doesn't work for me either, composite keys aren't working in 2.3.4

Can we get a fix for this?





[DDC-2363] Duplicated record with orphanRemoval and proxy Created: 22/Mar/13  Updated: 27/Mar/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Manuele Menozzi Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orphanRemoval, proxy
Environment:

Tested both Mac OS X and Ubuntu


Issue Links:
Duplicate
is duplicated by DDC-2364 [GH-625] [DDC-2363] Duplicated record... Open

 Description   

There is a problem that causes duplicate records are created when EntityManager has to remove an entity due to orphanRemoval. The problem occurs only with a double flush and referred object is a proxy.

I'm trying to submit a pull request for this ticket. Please, stand by.



 Comments   
Comment by Marco Pivetta [ 27/Mar/14 ]

Hey Manuele Menozzi, do you remember if this has been fixed? Are you still able to reproduce the problem?

Comment by Manuele Menozzi [ 27/Mar/14 ]

Hi Marco,
I made a PR (https://github.com/doctrine/doctrine2/pull/625) with an automated test that reproduce the problem. I just ran this test over latest version of doctrine2 and it's still failed. So, the problem has not be fixed and I (or you) can reproduce it easily.

Let me know if I can help you somehow.

Comment by Marco Pivetta [ 27/Mar/14 ]

Thanks, didn't see it!





[DDC-2193] Named native query bug? Created: 11/Dec/12  Updated: 31/Dec/12

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

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

Attachments: File DDC2193Test.php    

 Description   

@NamedNativeQueries is a useful thing, but I have found some problems during my using.
1、Normal

 /**
 * @NamedNativeQueries({
 *      @NamedNativeQuery(
 *          name            = "fetchMultipleJoinsEntityResults",
 *          resultSetMapping= "mappingMultipleJoinsEntityResults",
 *          query            = "SELECT * FROM test "
 *      )
 * })
 */

2、Error,cannot connect to the server

 /**
 * @NamedNativeQueries({
 *      @NamedNativeQuery(
 *          name            = "fetchMultipleJoinsEntityResults",
 *          resultSetMapping= "mappingMultipleJoinsEntityResults",
 *          query            = "SELECT * 
            FROM test "
 *      )
 * })
 */

3、Cannot use alias.The same problem as the second one.

.......
 query            = "SELECT a as test FROM test "


 Comments   
Comment by Fabio B. Silva [ 12/Dec/12 ]

Hi

Doctrine does not change the native query at all
The problem seems related with database connection.

Could you provide more details please?

Cheers

Comment by dingdangjyz [ 13/Dec/12 ]

Doctrine\Common\Lexer.php

Hello, after checking, I found the problem should be here. As long as SQL wrap, or fill in alias, it will be error. It seems to be the preg_split problem?

        $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
        $matches = preg_split($regex, $input, -1, $flags);

        foreach ($matches as $match) {
            // Must remain before 'value' assignment since it can change content
            $type = $this->getType($match[0]);

            $this->tokens[] = array(
                'value' => $match[0],
                'type'  => $type,
                'position' => $match[1],
            );
Comment by Fabio B. Silva [ 13/Dec/12 ]

Hi

Could you try to add a failing test case please ?

Cheers

Comment by dingdangjyz [ 14/Dec/12 ]

xp php5.3.8 Apache

<?php

namespace Models\Entities;

/**
 * @Entity
 * @Table
 *
 * @NamedNativeQueries({
 *      @NamedNativeQuery(
 *          name             = "find-hotel-item",
 *          resultSetMapping = "mapping-find-item",
 *          query            = "SELECT Top 1 VEI_SN AS SN 
            FROM tourmanager.dbo.VEndorInfo vi 
INNER JOIN tourmanager.dbo.VEndorInfo2 vi2 ON 
vi.VEI_SN = vi2.VEI2_VEI_SN LEFT OUTER JOIN tourmanager.dbo.HotelInfo hi 
ON hi.hotelid = vi2.VEI2_VEI_SN INNER JOIN tourmanager.dbo.HotelInfo2 
hi2 ON hi2.hotelid = vi2.VEI2_VEI_SN AND hi2.LGC = 1 "
 *      )
 * })
 *
 * @SqlResultSetMappings({
 *      @SqlResultSetMapping(
 *          name    = "mapping-find-item",
 *          entities= {
 *              @EntityResult(
 *                  entityClass = "HTHotelItem",
 *                  fields = {
 *                      @FieldResult(name = "id",   column="SN")
 *                  }
 *              )
 *          }
 *      )
 * })
 *
 */

class HTHotelItem{
    /** @Id @Column(type="integer") @GeneratedValue */
    protected $id;
        
    /** @name */
    protected $name;
    
    /** @city */
    protected $city;
    
    /** @url */
    protected $url;
    
    public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata){
        $metadata->addNamedNativeQuery(array(
            'name'              => 'find-hotel-item',
            'query'             => 'SELECT h FROM HTHotelItem h',
            'resultSetMapping'  => '\\Models\\Entities\\HTHotelItem'
        ));
    }
    
    function getId(){
        return $this->id;
    }
    
    function getName(){
        return $this->name;
    }
    
    function getCity(){
        return $this->city;
    }
    
    function getUrl(){
        return $this->url;
    }
}
Comment by dingdangjyz [ 14/Dec/12 ]

@NamedNativeQueries query

If we write the long SQL, it will be fault. NO error massage.
1251 charecter must be wrong.
I still insist it is the problem of preg_split in
Doctrine\Common\Lexer.php

Comment by Fabio B. Silva [ 16/Dec/12 ]

Can't reproduce,

Could you try to change the attached test case and make it fail.

Cheers

Comment by Benjamin Eberlei [ 24/Dec/12 ]

The Doctrine\Common\Lexer is never used in combination with native queries, only with the Annotation Parser, so i cannot be the preg_split that causes your SQL to be broken. Or do you get annotation errors?

Also what database are you using? maybe its related to the DBAL sql parsing?

Comment by dingdangjyz [ 31/Dec/12 ]

I'm sorry my English is too bad.

I think it's Doctrine \ is \ Lexer. PHP preg_split the function of the problem in this file.
My system environment is xp/apache 5.3 + / php_pdo_sqlsrv_53 / mssql2000





[DDC-2184] [GH-530] Singular form of generated methods should end with 'y' when property ends with 'ies' Created: 04/Dec/12  Updated: 05/Mar/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.3
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Duplicate
duplicates DDC-2150 EntityGenerator.php - Guessing singul... Resolved
duplicates DDC-2160 [GH-520] Fix for Doctrine\ORM\Tools\E... Resolved

 Description   

In Doctrine 2.3 the 'add' and 'remove' methods in oneToMany associations have another problem (in earlier versions like 2.2 this worked correct). The singular form is not correctly detected if the property ends with 'ies' like 'entries' which should be transformed to 'entry'.
I have this YAML definition:

Archive:
  type: entity
  fields:
    id:
      id: true
      type: integer
      unsigned: false
      nullable: false
      generator:
        strategy: IDENTITY
  oneToMany:
    entries:
      targetEntity: Entry
      mappedBy: archive

This generates these methods:

public function addEntrie(\Entry $entries) { ... }
public function removeEntrie(\Entry $entries) { ... }

Because in the EntityGenerator only the plural 's' is removed. It would be nice if an ending of 'ies' could be replaced by 'y'. So that we get these methods

public function addEntry(\Entry $entries) { ... }
public function removeEntry(\Entry $entries) { ... }

My fork already has the changes https://github.com/naitsirch/doctrine-orm2/commit/a3adfccb4927d61da7debae46ed0fff61e4212f8
I have opened a pull request here https://github.com/doctrine/doctrine2/pull/530



 Comments   
Comment by Christian S. [ 04/Dec/12 ]

Sorry, I accidently clicked on the button 'Request Feedback'
Now the status has changed to 'Awaiting Feedback'

Comment by Benjamin Eberlei [ 06/Jan/13 ]

Mark as improvement

Comment by Ed Page Croft [ 04/Jul/13 ]

Is this issue going to be resolved? It's a major problem for our project - a stock market application that uses properties like 'securities' and entities of name 'Security'.

Comment by Doctrine Bot [ 05/Mar/14 ]

A related Github Pull-Request [GH-530] was closed:
https://github.com/doctrine/dbal/pull/530





[DDC-2147] Custom annotation in MappedSuperclass Created: 15/Nov/12  Updated: 07/May/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers, ORM
Affects Version/s: 2.2.1
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: kluk Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux 3.6.6-1.fc17.x86_64


Attachments: Text File error.log    

 Description   

When you try use custom annotation in mappedsuperclass like here http://pastebin.com/YMxKvcLk and then i try get metadata for class i get this error
Undefined index: fieldName
ClassMetadataInfo.php function addInheritedFieldMapping
Problem is that custom annotation doesnt have fieldName.
Quick fix is add condition to test if fieldName isset.



 Comments   
Comment by kluk [ 15/Nov/12 ]

error log from orm:validate-schema

Comment by Marco Pivetta [ 23/Jan/13 ]

Copying from pastebin:

use \Doctrine\ORM\Mapping as ORM;
use \xxx\Doctrine\Annotation\Entity as re;
use \xxx\Doctrine\Annotation\Forms as rf;
use \Doctrine\Common\Collections;
 
/**
 * @ORM\Entity
 */
class EventPicture extends \Picture
{
 
    /**
     * @ORM\ManyToOne(targetEntity="Event", inversedBy="eventPicture")
     * @ORM\JoinColumn(name="FK_Event", referencedColumnName="id")
     */
    protected $event;
 
}
use \Doctrine\ORM\Mapping as ORM;
use \xxx\Doctrine\Annotation\Entity as re;
use \xxx\Doctrine\Annotation\Forms as rf;
use \Doctrine\Common\Collections;
 
/** @ORM\MappedSuperclass */
class Picture extends \xxx\Doctrine\Entity\BaseEntity
{
 
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @var type
     */
    protected $id;
 
    /**
     * @ORM\Column(type="string",unique=true, nullable=false)
     *  @rf\FileUpload(fileSize="php",uploadType="local",fieldName="link",formControl="FileUploadField",image=true)
     *
     */
    protected $link;
 
}

kluk does this happen also with any other simple custom annotation? For example following:

/**
 * @Annotation 
 * @Target({"PROPERTY","ANNOTATION"})
 */
final class Entity implements Annotation
{
    /**
     * @var string
     */
    public $value;
}
Comment by kluk [ 30/Jan/13 ]

the same error when using simple annotation.

 
<?php

use \Doctrine\ORM\Mapping as ORM;
use \xxx\Doctrine\Annotation\Entity as re;
use \xxx\Doctrine\Annotation\Forms as rf;
use \Doctrine\Common\Collections;

/** @ORM\MappedSuperclass */
class Picture extends \xxx\Doctrine\Entity\BaseEntity {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @var type
     */
    protected $id;

   
    /**
     * @ORM\Column(type="integer")
     * @rf\SetClass({"class","hide"})
     */
    public $value;

    /**
     * @ORM\Column(type="string",unique=true, nullable=true)
     * @rf\FileUpload(fileSize="php",uploadType="local",fieldName="link",formControl="FileUploadField",image=true)
     *
     */
    protected $link;

}

When i remove $value , $picture from class everything goes ok.
Easy fix for me is change ClassMetadataInfo.

    /**
     * INTERNAL:
     * Adds a field mapping without completing/validating it.
     * This is mainly used to add inherited field mappings to derived classes.
     *
     * @param array $fieldMapping
     *
     * @return void
     */
    public function addInheritedFieldMapping(array $fieldMapping)
    {
        if(isset($fieldMapping['fieldName'])){
        $this->fieldMappings[$fieldMapping['fieldName']] = $fieldMapping;
        $this->columnNames[$fieldMapping['fieldName']] = $fieldMapping['columnName'];
        $this->fieldNames[$fieldMapping['columnName']] = $fieldMapping['fieldName'];
        }
    }

But i dont know if this fix can break another part of doctrine.

Comment by Benjamin Eberlei [ 04/May/13 ]

Can you put the code of your annotations online? I can't seem to understand why this happens.

Comment by kluk [ 07/May/13 ]
Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
 
namespace libs\Doctrine\Annotation\Entity;
use Doctrine\Common\Annotations\Annotation;

/** @Annotation */
class CustomMapping extends Annotation
{
    /**
     *
     * @var string
     */
    public $className;
    /**
     * 
     * 
     * @var IQueryable| string
     */
    public $dataSource;
}




[DDC-1986] findBy hydration with limit and offset with Oracle database (oci8 driver) Created: 17/Aug/12  Updated: 08/Jan/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Grandfond Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: oracle
Environment:

composer.json require :

"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "dev-master",
"twig/extensions": "dev-master",
"symfony/assetic-bundle": "dev-master",
"symfony/swiftmailer-bundle": "dev-master",
"symfony/monolog-bundle": "dev-master",
"sensio/distribution-bundle": "dev-master",
"sensio/framework-extra-bundle": "dev-master",
"sensio/generator-bundle": "dev-master",
"jms/security-extra-bundle": "1.2.*",
"jms/di-extra-bundle": "1.1.*",
"twitter/bootstrap": "master",
"friendsofsymfony/rest-bundle": "dev-master",
"doctrine/doctrine-fixtures-bundle": "dev-master"



 Description   

I tried to use the findBy method with limit and offset parameters against an Oracle database using oci8 driver.

The query seems to executed successfully but the hydrator fails when hydrating data as there is a DOCTRINE_ROWNUM column appending the "limit" clause.

Here is the exception thrown : "Notice: Undefined index: DOCTRINE_ROWNUM in [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php line 183"

I was thinking about something like this to fix this issue :

  • add an attribute (platformExtraColumns) to the platform class, storing every column added by methods like doModifyLimitQuery
  • check in hydrator method hydrateRowData if the column exists among the extra columns attribute of the custom platform
  • don't use the column if true

Maybe there is a better approach, what are your thoughts?



 Comments   
Comment by Benjamin Grandfond [ 17/Aug/12 ]

I implemented it in my forks :

https://github.com/benja-M-1/doctrine2/commit/c8d899b14446accf869ddc0043f4235284375755
https://github.com/benja-M-1/dbal/commit/b9423c8d46a2bcdaa5a1f0b26a9a28259b1e44a2

It works for me, but I didn't write unit tests.

Comment by Benjamin Grandfond [ 24/Aug/12 ]

Hi,

Did you have time to have a look at this issue?

Thanks

Comment by Christophe Coevoet [ 24/Aug/12 ]

Please send a pull request when you submit a fix. It is the proper way to submit them for review. When we want to see things waiting for review, we look at the list of pending PRs, not at all comments of the issue tracker to find links in them.

And I can tell you that this change has a big issue: it introduces a state in the database platform whereas it is currently stateless. This is likely to cause some issues when using more than 1 query (which is a common use case).

Comment by Benjamin Grandfond [ 29/Aug/12 ]

Hi Christophe thank you for your feedback.

I didn't send a PR because I wanted someone sharing his thoughts about what I suggested in this current issue. However I don't really understand the stateless argument, can you explain a bit more?

Otherwise how would do you proceed to tell Doctrine not to hydrate platform-specific columns?

Comment by Christophe Coevoet [ 29/Aug/12 ]

If you run several queries, they will be affected by the extra columns of previous requests, which is wrong

Comment by Benjamin Eberlei [ 29/Aug/12 ]

I think the ObjectHydrator catches this by skipping undefined columns, i think we might just have overoptimized the SimpleObjectHydrator a little bit.





[DDC-1879] Orphans are neither nulled nor removed when merging a graph of detached entities Created: 18/Jun/12  Updated: 23/Jan/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Philippe Van Eerdenbrugghe Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Doctrine 2.2.2
PHP 5.3.10 with Suhosin-Patch
mysql Ver 14.14 Distrib 5.5.15, for osx10.7
Mac OS X 10.7 Lion



 Description   

When merging a graph of detached entities, the created entitied are created and the updated entities are updated but the non-present entities (which exist in the database but are not in the graph) are neither removed nor have them their association column nullified.

Example :

In my code I have 2 entities : Parent and Child. There is a OneToMany(cascade=

{"all"}

, orphanRemoval=true) relation defined in Parent.

In my database I have a Parent row with an id of 1, which has 3 Children with ids 1,2,3.

When I write the following code, I expect the Parent with id 1 and the Child with id 2 to be updated, a new Child to be created and the Child with id 1 and 3 to be deleted.

$parent = new Parent(); $parent->id = 1  // detached entity
$existing_child = new Child(); $child->id = 2 // detached entity
$new_child = new Child(); // new entity
$dinner->addChild($existing_child);
$dinner->addChild($new_child);

$em->merge($dinner);

$em->flush();

The objects I expect to be created and updated have the correct behaviour but the old children are not touched, they are still present in the database.



 Comments   
Comment by Marco Pivetta [ 23/Jan/13 ]

I don't think this is valid. Orphan removal scheduling is handled only when an unit of work is available.

What's the state of `$dinner` before your example? Can you `var_dump` it?





[DDC-1803] Paginator usage with a DQL query that is using 2 time the same named binded value failed Created: 30/Apr/12  Updated: 25/Jan/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Marc Drolet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

linux, oracle



 Description   

I use a dql query where I bind a named parameter 2 time in the same query for different joined fields. The query work but the count query failed saying that there are missing bind variable.

ex:
$qb = $this->getQueryBuilder()
->select('
partial fl.

{id, title, listing_date, abstract}

,
partial fla.

{id},
partial ca.{id}

,
partial ds.

{id}

')
->from('Fo_Listing', 'fl')
->join('fl.listing_properties', 'flp')
->join('flp.property', 'fp')
->leftjoin('fl.listing_assets', 'fla')
->leftjoin('fla.asset', 'ca')
->leftjoin('ca.ds', 'ds')
->where('fp.id = :propertyId')
->setParameter('propertyId', $id)
->andWhere('fl.object_status_id <> :deleted')
->setParameter('deleted', CoRefObjectStatus::DELETE)
->andWhere('fl.publishing_status_id = :published')
->setParameter('published', CoRefPublishingStatus::PUBLISHED)
->andWhere('fp.object_status_id <> :deleted')
->setParameter('deleted', CoRefObjectStatus::DELETE)
->andWhere('fp.publishing_status_id = :published')
->setParameter('published', CoRefPublishingStatus::PUBLISHED)
->add('orderBy', 'fl.listing_date DESC, fl.published_date DESC')
->setMaxResults($onTheMarketLimit);

$onTheMarket = new Paginator($qb, $fetchJoin = true);

To make it work, I've renamed the second usage of the named variable with a 2 at the end. deleted2 and published2.



 Comments   
Comment by Marco Pivetta [ 23/Jan/13 ]

This seems to be quite old. Marc Drolet is it still valid with the latest ORM?

Comment by Marc Drolet [ 25/Jan/13 ]

I'll try to test this problem on an updated version and I'll let you know.
The bug entry is also quite old and I've a local modified version of the paginator here to make it work with oracle, so it can take some time before I can test this out on the current doctrine version.

Comment by Marco Pivetta [ 25/Jan/13 ]

Ok, marking as awaiting feedback





[DDC-1721] LIKE clausule should accept functions on the pattern Created: 21/Mar/12  Updated: 01/Apr/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.6
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Ignacio Larranaga Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: querybuilder,, sql-walker

Attachments: Text File Parser.patch     Text File SqlWalker.patch    

 Description   

Example:
SELECT .... WHERE upper(n.title) LIKE upper(:filter)

should be a valid SQL, now is rejected because the walker only accept a variable or an string expression.

I'm adding a patch to address this.



 Comments   
Comment by Ignacio Larranaga [ 21/Mar/12 ]

Sorry the Parser has to be modified also to allow expressions to be recognized, I'm attaching the necessary patch.

Comment by Benjamin Eberlei [ 22/Mar/12 ]

I am sure there is a reason why the walker doesn't accept this such as not all supported vendors allowing functions in right hand side LIKE expressions, but i am not sure about this.

Comment by Glen Ainscow [ 03/Oct/12 ]

This is not possible either:

WHERE CASE WHEN p.name IS NULL THEN u.username ELSE p.name END LIKE :name

Comment by Thomas Mayer [ 24/Jan/13 ]

In my case it worked when using "=" instead of "LIKE".

//works:
(CASE WHEN (Book.id = BookFrom.id) THEN BookTo.displayName ELSE BookFrom.displayName END) = :name

//[Syntax Error] line 0, col 1217: Error: Expected =, <, <=, <>, >, >=, !=, got 'LIKE'
(CASE WHEN (Book.id = BookFrom.id) THEN BookTo.displayName ELSE BookFrom.displayName END) LIKE :name

So the LIKE operator only needs to be allowed here.

I'm wondering which vendor should not be able to handle that:
The CASE WHEN ... THEN ... END is documented in DQL, and allowed.
LIKE itself is allowed.
If an RDBMs cannot use CASE WHEN and LIKE in combination, this would be a strange limitation.

Comment by Martin Keckeis [ 31/Mar/14 ]

Having the same problem here.

LIKE + CASE is often used in my application at the WHERE part.
(e.g. data filtering of a datagrid column)





[DDC-2988] Notice: Undefined index: joinColumns in BasicEntityPersister.php Created: 19/Feb/14  Updated: 13/Jun/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.3.5, 2.4.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Dennis Væversted Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File undefined-joinColumn.patch    
Issue Links:
Duplicate
duplicates DDC-2808 Notice: Undefined index: joinColumns ... Resolved

 Description   

When trying to use findBy on a ManyToMany field i receive the error:

Notice: Undefined index: joinColumns in lib/Doctrine/ORM/Persisters/BasicEntityPersister.php

It seems to be caused internally by the code expecting 'joinColumns' to be directly on the association, however it is found under 'joinTable'.
I have attached a patch that atleast fixes my case, hopefully it can be used to pin-point what the error is.



 Comments   
Comment by Dennis Væversted [ 19/Feb/14 ]

Might be related to this one: http://www.doctrine-project.org/jira/browse/DDC-2808

Comment by Litz Ouille [ 28/May/14 ]

Doctrine ORM 2.4.2 Here.

Here are my annotations
https://gist.github.com/LitzOuille/3cf2e73e169c032147ea

The thing I'm trying to do is
$questionRepository->findBy(array('contacts' => $ids)); // $ids = array(1,2,3, ...)

Comment by Marco Pivetta [ 30/May/14 ]

Calin Pristavu did you validate your mappings?

Comment by Calin Pristavu [ 30/May/14 ]

I failed, sorry.
The error came from the many-to-many condition in the entity.
Sorry for generating confusion, comment deleted !

The many-to-one works just fine !

Comment by Litz Ouille [ 03/Jun/14 ]

A little feedback? Is this a bug? Can it be fixed?
Thanks

Comment by Marco Pivetta [ 03/Jun/14 ]

Litz Ouille that particular repository call cannot work. How are we supposed to find an entity from a list of associated IDs? It would have to be the exact match...

Assuming that API would work as I envision it, it looks like a missing feature.

Dennis Væversted in order to accept a patch, we first need a failing test case demonstrating the failing scenario.

Comment by Litz Ouille [ 03/Jun/14 ]

EDIT: Ok my bad.

I am using findBy(array('id', $arrayIds)) and it is working. I thought I was using on a ManyToOne relationship, but no.

EDIT2: @ocramius In fact I would like to find all questions for which the contacts' list contains at least one id. Something like
SELECT q.*
FROM Question q, QuestionContact qc //qc = jointable
WHERE q.id = qc.question_id
AND qc.contact_id IN ($ids)

EDIT3: Actually when I try to findBy('ManyToMany', $id), it does not work either. I think I will have to use a repository for every query using a ManyToMany relationship.

EDIT4: Ok, so, as said in the original post, findBy does not work with many-to-many.
Notice: Undefined index: joinColumns (BasicEntityPersister.php line 1666)
Dump($this->class->associationMappings[$field]): https://gist.github.com/LitzOuille/51929fdc3eda5576ed31

Comment by Xander ten Boden [ 13/Jun/14 ]

I've got the same issue, also running doctrine 2.4.2:

multiple users can have multiple departments:

/**
 * @ORM\ManyToMany(targetEntity="CartelAuthDepartment", inversedBy="users")
 * @ORM\JoinTable(name="cartel_auth_user_has_cartel_auth_department",
 *		joinColumns={@ORM\JoinColumn(name="cartel_auth_user_id", referencedColumnName="id")},
 *		inverseJoinColumns={@ORM\JoinColumn(name="cartel_auth_department_id", referencedColumnName="id")}
 * )
 */
private $departments;

/**
 * @ORM\ManyToMany(targetEntity="\Cartel\AuthBundle\Entity\CartelAuth\CartelAuthUser", mappedBy="departments")
 */
private $users;

Then I want to find all the users that are within the departments that the current user has:

$aAuthUsers = $oEm->getRepository('CartelAuthBundle:CartelAuth\CartelAuthUser')->findByDepartments($aAuthDepartments);

This results in this error:

Notice: Undefined index: joinColumns in .../vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1665





[DDC-2332] [UnitOfWork::doPersist()] The spl_objact_hash() generate not unique hash! Created: 05/Mar/13  Updated: 08/Jul/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Krisztián Ferenczi Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 2.1.8, php 5.4.7 and php 5.4.12, Windows 7


Attachments: Text File hashlogs.txt    

 Description   

I created fixtures and some data was inserted many times without calling the Task entity PrePersist event listener.

I printed the used and generated hash and I saw a Proxies_CG_\Asitly\ProjectManagementBundle\Entity\User hash equal a Task entity hash!



 Comments   
Comment by Marco Pivetta [ 05/Mar/13 ]

Please provide either a code example or a test case. As it stands, this issue is incomplete

Comment by Benjamin Eberlei [ 05/Mar/13 ]

Are you calling EntityManager#clear() inbetween? Because PHP reuses the hashes. The ORM accounts for this.

Comment by Benjamin Eberlei [ 05/Mar/13 ]

This is not a reproduce case, i don't want to execute your whole project.

I want to know, what is the actual bug that you see? Can you just print a list of all the hashes? Because the hashes dont differ at the end, bu tjust somewhere in the middle.

Comment by Krisztián Ferenczi [ 05/Mar/13 ]

I attached a hashlogs.txt file. The last Task class hash is 0000000050ab4aba0000000058e1cb12 ( line 3 129 )

This is not unique, view the line 2 760 . The Task is not being saved and the program don't call the prePersist listener. The "UnitOfWork" believe the entity has been saved because the isset($this->entityStates[$oid]) is true. But it is an other entity.

Comment by Krisztián Ferenczi [ 06/Mar/13 ]

The EntityManager::clear() fix the problem, but this is not "good" and "beautiful" solution. Shows no sign of that conflicts were and this is causing the problem. I was looking for the problem 7 hours.

Comment by Marco Pivetta [ 26/Jun/14 ]

One possible issue here is that a listener registers an entity as managed while a proxy is being loaded.

The given data is still insufficient to actually verify the problem.





[DDC-3238] GROUP BY does not work as expected in MS SQL Server Created: 31/Jul/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.4.1, 2.4.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Spencer Weiss Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MS SQL Server 2012



 Description   

Running the query taken from this page: <http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html>

$query = $em->createQuery('SELECT u, count(g.id) FROM FundAsset u JOIN u.locations g GROUP BY u.id');

I receive the following error from MS SQL Server:

SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Column 'fund_assets.active' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

It appears that Doctrine's GROUP BY clause does not work correctly in Microsoft SQL Server.



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

Needs a failing test case.





[DDC-3231] [GH-1089] Entity repository generator default repository Created: 27/Jul/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of encoder32:

Url: https://github.com/doctrine/doctrine2/pull/1089

Message:

1) I set default repository class in configuration to MyApp\Doctrine\DefaultRepository
2) I created entity class MyApp\Entity\TestEntity and generated repository class for it
3) Actually the repository class "MyApp\Entity\TestEntityRepository" turned out to be a descendant of "Doctrine\ORM\EntityRepository" when I expected "MyApp\Doctrine\DefaultRepository" as default.

Related pull request https://github.com/doctrine/DoctrineBundle/pull/315






[DDC-3088] EntityManager::clear doesn't working with inserting Created: 16/Apr/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Adrian Ch Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.4.25-1+sury.org~precise+2 (cli) (built: Feb 12 2014 10:45:30)
Symfony version 2.4.2 - app/dev/debug



 Description   

It looks like EntityManager's clear() method doesn't remove objects that was persisted during script execution.

Bellows are two functions. First one insert 10.000 records and use clear after each flush that should remove objects from memory, but instead of that memory usage growths in each iteration. There isn't any other reference for this objects.

I've checked how it works for reading and with clearing it works perfectly - script uses only constant memory.

 
    private function testInserting($em, $entityClass, $batchSize, $startMemoryUsage)
    {
        for ($i = 1; $i <= 10000; ++$i) {

            $item = new $entityClass();
            $item->setName($i);
            $item->setPresentation($i);
            $em->persist($item);

            if ($i % $batchSize == 0) {
                $em->flush();
                $em->clear();

                $currentMemoryUsage = memory_get_usage();
                printf("%d:\n\t%.2f MB (%.2f MB)\n", $i, $currentMemoryUsage /1024 / 1024, ($currentMemoryUsage - $startMemoryUsage) / 1024 / 1024);
            }
        }
    }
    
    
private function testReading($em, $entityClass, $batchSize, $startMemoryUsage)
    {
        $q = $em->createQuery("select i from $entityClass i");
        $iterableResult = $q->iterate();

        $i = 0;
        while (($row = $iterableResult->next()) !== false) {
            $em->clear();
            if ($i % $batchSize == 0) {
                $currentMemoryUsage = memory_get_usage();
                printf("%d:\n\t%.2f MB (%.2f MB)\n", $i, $currentMemoryUsage /1024 / 1024, ($currentMemoryUsage - $startMemoryUsage) / 1024 / 1024);
            }

            $i++;
        }
    }
    

My results:

1) Reading without clearing ($em->clear(); removed)

0:
22.89 MB (2.63 MB)
1000:
33.41 MB (13.15 MB)
2000:
44.04 MB (23.78 MB)
3000:
53.50 MB (33.24 MB)
4000:
65.13 MB (44.86 MB)
5000:
74.81 MB (54.55 MB)
6000:
84.27 MB (64.01 MB)
7000:
97.96 MB (77.69 MB)
8000:
107.40 MB (87.14 MB)
9000:
117.17 MB (96.91 MB)
10000:
126.61 MB (106.35 MB)

2) Reading with using clear

0:
22.89 MB (2.63 MB)
1000:
26.25 MB (5.99 MB)
2000:
24.74 MB (4.48 MB)
3000:
26.72 MB (6.46 MB)
4000:
24.79 MB (4.52 MB)
5000:
26.76 MB (6.50 MB)
6000:
24.81 MB (4.55 MB)
7000:
26.77 MB (6.51 MB)
8000:
24.83 MB (4.57 MB)
9000:
26.81 MB (6.54 MB)
10000:
24.86 MB (4.60 MB)

3) Inserting without clearing

1000:
29.50 MB (9.24 MB)
2000:
37.76 MB (17.50 MB)
3000:
45.12 MB (24.86 MB)
4000:
54.34 MB (34.07 MB)
5000:
61.79 MB (41.53 MB)
6000:
69.09 MB (48.82 MB)
7000:
76.40 MB (56.13 MB)
8000:
83.75 MB (63.48 MB)
9000:
95.64 MB (75.37 MB)
10000:
102.98 MB (82.71 MB)

4) Inserting with using clear

1000:
27.90 MB (7.63 MB)
2000:
34.64 MB (14.37 MB)
3000:
40.43 MB (20.17 MB)
4000:
48.20 MB (27.93 MB)
5000:
54.12 MB (33.85 MB)
6000:
59.89 MB (39.63 MB)
7000:
65.67 MB (45.40 MB)
8000:
71.43 MB (51.16 MB)
9000:
81.51 MB (61.25 MB)
10000:
87.29 MB (67.02 MB)



 Comments   
Comment by Marco Pivetta [ 16/Apr/14 ]

Would be useful to see what the entity class looks like.

Additionally, the ORM version being affected is also needed.





[DDC-2922] Flushing new Entities reachable over several paths that do not all "cascade persist" Created: 17/Jan/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Matthias Pigulla Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Please consider the following associations:

  A <>--> B <-- C  

A is an "aggregate" type object w/ a OneToMany collection of Bs. This association is set to cascade persist operations.

C has a unidirectional OneToOne association to B as well.

Adding a new B to A's collection and flushing the EntityManager works - B is persisted (persistence by reachability).

However, when also creating a new C and pointing it to the new B, adding C to the EntityManager and then flushing leads to an exception because B is discovered as a new Entity through a relationship not set to cascade persist operations.

Obviously the problem here is that there are two paths through which we can discover new Entities. The UoW currently starts search from newly (explicitly) added Entities first before it walks through collections of already-managed entities.

I am unsure if it is just a documentation issue or a deeper problem?

If the UoW worked the other way round, the same problem would occur if the cascade persist was on the other association.

A solution would probably require the UoW to first collect all offending (new) Entities and the link they were discovered through, but later on remove Entities from this list if they are found through another association with the cascade persist option. The exception must not be thrown unless the whole reachability graph has been traversed.



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

Can this be factored into a failing test case? I'm not sure if we can support it, but the code would make it much easier to track down the issue into something fixable.





[DDC-2881] [GH-895] Fix for no dot on Class Names Created: 04/Jan/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of sinner:

Url: https://github.com/doctrine/doctrine2/pull/895

Message:

If you work with PostgreSQL Schemas, You should filter the names of table to generate Correct name for PHP Classes. This way allow not write dots (.) as part of the Class Name.

Additionally, there is a variable ($schema) that must be contained in the class "Doctrine\DBAL\Schema\Table" on an $schema possible property but this is not available. (recomended)






[DDC-2945] [GH-925] [DDC-2310] [DDC-2675] [2.4] Fix SQL generation on table lock hint capable platforms Created: 31/Jan/14  Updated: 18/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Steve Müller
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of deeky666:

Url: https://github.com/doctrine/doctrine2/pull/925

Message:

Backport of PR https://github.com/doctrine/doctrine2/pull/910 for 2.4 branch.






[DDC-2901] entity-listeners are not propagated to children of mapped superclasses Created: 09/Jan/14  Updated: 19/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.1
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Stuart Carnie Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: mapping


 Description   

If I have event-listeners set on the subclass and mapped superclass, event-listeners will not be propagated, per this code. Conversely, lifecycle events are, per this



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

Stuart Carnie I lost the code references that you linked, since the code changed and the line numbers don't match anymore.

Any chance that you can provide a failing test for this issue, as well as update the links to reference a fixed commit hash or tag?

Comment by Stuart Carnie [ 19/Aug/14 ]

Marco Pivetta, I've updated the URIs in the description to the right tree

Comment by Marco Pivetta [ 19/Aug/14 ]

The code explicitly forbids inheriting listeners when the child class does not have any.

Fabio B. Silva can you provide any insight on why this decision was made?





[DDC-3029] DISTINCT , ORDER BY AND Limit in SQL Server Created: 14/Mar/14  Updated: 20/Aug/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Michał Banaś Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File SQLServerPlatform.php    

 Description   

I don't know if I should report it here , becouse error is in SQLServerPlatform.php file.
basicaly Distinct includes ROWNUM()
So if you add distinct in DQL it will be translated to "select distinct ...... , Rownum()" - which is always distinct offcource.

Here is original version

    protected function doModifyLimitQuery($query, $limit, $offset = null)
    {
        if ($limit > 0) {
            if ($offset == 0) {
                $query = preg_replace('/^(SELECT\s(DISTINCT\s)?)/i', '\1TOP ' . $limit . ' ', $query);
            } else {
                $orderby = stristr($query, 'ORDER BY');

                if ( ! $orderby) {
                    $over = 'ORDER BY (SELECT 0)';
                } else {
                    $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby);
                }

                // Remove ORDER BY clause from $query
                $query = preg_replace('/\s+ORDER BY(.*)/', '', $query);
                $query = preg_replace('/^SELECT\s/', '', $query);

                $start = $offset + 1;
                $end = $offset + $limit;

                $query = "SELECT * FROM (SELECT ROW_NUMBER() OVER ($over) AS doctrine_rownum, $query) AS doctrine_tbl WHERE doctrine_rownum BETWEEN $start AND $end";
            }
        }

        return $query;
    }

In Attachenment there is a fixed version of this file.



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

Can you provide a failing test case and an expected result as well?

Comment by Michał Banaś [ 20/Aug/14 ]

Well I'm not working with PHP anymore for now, but i will try:
it's easy and when you look at the code closer you will see the problem:

Test Case: use Query Builder and genearate query with DIstinct and Order BY And Liimit ( top , skip or something )
Expected result would be to get distinct set of data ordered by key and with limit.
Unfortunately - as the result query will be something:
select distinct .... top ....
from .........
SELECT ROW_NUMBER() OVER ($over) AS doctrine_rownum ... rest of the qurery

so from inner query you will get

doctrine_rownum;column1;column2;column3
1;example;example;example
2;example;example;example
3;example;example;example

I think you can clearly see that each row will be diiffrent. That's why DISTINCT will not work.
What happens next:
At some point doctrine will treat identical entities as one object, so for example if you limit Your query to 10 and all objects will be identical You will get only one Row.

I hope thats clear now

And we have a solution for that. It's probably in attached file. I will try to attach final version

My team is woried that after updating Doctrine ( symfony ) we will have to face the problem again.

Comment by Michał Banaś [ 20/Aug/14 ]

well. For some reason i can't attach final version of the file :/
I can paste it as a comment or You can contact me directly and i will send it to You.

Comment by Marco Pivetta [ 20/Aug/14 ]

Ah, I see now what the problem is. ROWNUM() will basically always make the row unique, making DISTINCT useless.

The problem is clear, but it needs an SQL generation test first.

Michał Banaś can you eventually send the patch as a pull request to https://github.com/doctrine/dbal ? Consider that the code for the SQLServerPlatform changed a lot since 2.4.x

Comment by Michał Banaś [ 20/Aug/14 ]

Well I could do that in private time, but it can take a while since i have no spare time right now and i would have to prepare some basic PPH dev environment with MSSQL.otherwise i would send untested code which is not a good idea.

Comment by Marco Pivetta [ 20/Aug/14 ]

We all do develop these tools in private time, so nobody is forcing anyone to do anything





[DDC-1756] Allow for master table only models on joined subclass inheritance Created: 03/Apr/12  Updated: 13/Sep/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Markus Wößner Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Think of a joined subclass inheritance setup where abstract base class A has many concrete child classes C1 ... CN. For each child class a table necessarily has to created. Yet if there are many child classes not defining any additional fields you will get many "id only" child tables. This leads to unnecessary join and insert overhead on database operations as well as a bunch of quite senseless tables in your schema that need to be maintained.

While there are already tickets requesting support for mixed inheritance mapping (e.g. DDC-138) I want to propose another - obviously easy to implement - solution that addresses the "id only table" problem. The basic idea is to extend ClassMetadata by a flag "hasOwnTable" which is true by default and applicable for child classes of a joined subclass tree. Setting this flag to <false> would lead to...
1.) no child table creation for corresponding model
2.) no joins to this table while rendering SQL from DQL statements
3.) no INSERT, UPDATE and DELETE statements for this table in methods executeInserts(), update() and delete() on Doctrine\ORM\Persisters\JoinedSubclassPersister.

(3) can easily be implemented since the mentioned methods all loop on ClassMetadata::parentClasses. For those classes which set the flag "hasOwnTable" to false the operation will be skipped. On the other hand (2) doesn't seem to a big deal either. Extending SqlWalker::_generateClassTableInheritanceJoins() by means of a flag test seems to be enough. Of course setting the flag to <false> while defining additional fields on child class level must be rejected.

If you go for this feature I would be pleased to provide an implementation.






[DDC-2406] Merging of new detached entities with PrePersist lifecycle callback breaks Created: 19/Apr/13  Updated: 14/Sep/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Oleg Namaka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: merge,, prePersist


 Description   

Merging of new detached entities with PrePersist lifecycle callback breaks:

Code snippet:

    class A
    {
       /**
        *  @ORM\ManyToOne(targetEntity= ...
        *  @ORM\JoinColumn(name=" ...
        */
        protected $b;
        
        public function getB()
        {
            return $this->b;
        }
        
        public function setB($b)
        {
            $this->b = $b;
        }
        
        /**
         *
         * @ORM\PrePersist
         *
         * @return void
         */
        public function onPrePersist()
        {
           if ($this->getB() === null) {
                throw new \Exception('B instance must be defined);
           }
           ....
        }
    }
    
    class B 
    {
    }
    
    $a = new A();
    $b = $em->find('B', 1);
    $a->setB($b);
    $em->persist($a); // works fine as B instance is set
    $em->detach($a);
    
    $a = $em->merge($a) // breaks in onPrePersist

The reason it happens is that the merge operation is trying to persist a new entity created by uow::newInstance($class) without populating its properties first:

 // If there is no ID, it is actually NEW.
    ....
    if ( ! $id) {
        $managedCopy = $this->newInstance($class);

        $this->persistNew($class, $managedCopy);
    } else {
	....

This should happen first for the $managedCopy:

    // Merge state of $entity into existing (managed) entity
    foreach ($class->reflClass->getProperties() as $prop) {
        ....


 Comments   
Comment by Fabio B. Silva [ 28/Apr/13 ]

Benjamin Eberlei, Is this an expected behavior ?

I mean.. This issue is about dispatch the event before copy the original values into the managed instance.
But overall, should $em->detach() trigger @PrePersist events ?

Comment by Benjamin Eberlei [ 01/May/13 ]

Fabio B. Silva he talks about $em->merge() on a detached entity calling pre persist. This should only happen on a NEW entity, not on a DETACHED one.

Comment by Oleg Namaka [ 01/May/13 ]

I tend to disagree with the statement above about pre persist that should not happen on a detached entity being merged back in. If this event handler contains a business logic that this entity needs to be checked against and the detached entity was modified before the merge operation in a way that invalidates it in the prePersist than I will end up with the invalid entity in the identity map. If the merge operation calls persist it must run the prePersist event handler as well for consistency.

If there is a logic that prevents persisting invalid entities why should it bypassed in the merge operation?

Comment by Cory Close [ 28/Nov/13 ]

I can confirm that this bug has not been fixed while using doctrine 2.4

Exactly as Oleg Namaka has described, my organization is trying to use @PrePersist callbacks to enforce validation on new entities.

However, we use an extensive client side framework that sends json back to our server. Our workflow is then:

deserializeJson into detached entity
merge detached entity to get it managed (this will apply our edits to an existing entity, or create a new one if this one is new)
persist

However, some entities run into the above problem while using this workflow, so our validation is not run. I can provide more code samples if required.

Comment by Oleg Namaka [ 29/Apr/14 ]

Whose feedback is it awaiting for?

Comment by Romaric Drigon [ 30/May/14 ]

I can confirm this issue.

My use case (which I guess is pretty standard):

  • I deserialize a new entity (with relationships to already existing ones)
  • I merge it to attach existing entities
  • I persist it

PrePersist is called on an entity with all properties set to null. Any modifications made inside this entity won't be saved to the DB.

Comment by Cory Close [ 30/May/14 ]

Is there any reason the proposed solution can't be implemented? I've patched a local version of Doctrine with the proposed changes and ran it through my application's tests without any issues, so I believe this would fix the problem.

Comment by Chris Johnson [ 14/Sep/14 ]

+ on this one. I also have a similar situation where I get a detached entity from an API and use merge to update any changed elements. Obviously there is a workaround (trigger the lifecycle's function manually), but would be great not to have to do this.





[DDC-2424] Removing an inherited entity via a delete cascade constraint does not remove the parent row Created: 02/May/13  Updated: 15/Oct/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.3.3, 2.4.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Bruno Jacquet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 3
Labels: inheritance, postgresql
Environment:

Mysql 5.1.66 / Symfony 2.2.1



 Description   

For a parent class:

/**
 * @ORM\Entity
 * @ORM\Table(name="Base")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"child1" = "Child1", "child2" = "Child2"})
 */

and simple Child1 & Child2 entities.

With another entity (let's call it ExternalEntity) having a bidirectional OneToOne relation owned by Child1:

class Child1 extends Base
{
  /**
   * @ORM\OneToOne(targetEntity="ExternalEntity", inversedBy="xxx")
   * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
   */
   private theForeignKey;
}

Enough for the context.
The symptoms:

$em->remove(instanceOfExternalEntity);

removes the ExternalEntity row and the Child1 row. But a dangling row in the Base table is still there for the now inexistent Child1 instance.

Though, a manual delete of either the associated Child1 OR Base row and then the ExternalEntity works.

The problem with the cascading deletion of the parent seems to be only present when deleting through a MYSQL cascading delete from another row which has a foreign key on a child. (Not tested with a foreign key on the parent though)



 Comments   
Comment by Benjamin Eberlei [ 04/May/13 ]

Can you show the CREATE TABLE and FOREIGN KEY statements of all the tables involved? It seems the cascade of the foreign keys is not propagated between multiple tables?

Comment by Bruno Jacquet [ 06/May/13 ]

CREATE TABLE Base (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE Child1 (id INT NOT NULL, foreignKey INT NOT NULL, UNIQUE INDEX UNIQ_179B6E88E992F5A (foreignKey), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E88E992F5A FOREIGN KEY (foreignKey) REFERENCES ExternalEntity (id) ON DELETE CASCADE;
ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E8BF396750 FOREIGN KEY (id) REFERENCES Base (id) ON DELETE CASCADE;

Comment by Bruno Jacquet [ 06/May/13 ]

The problem is that, the SQL model never explicitely tells the DB to delete the corresponding Base when Child1 gets removed. It looks like it is handled by the doctrine entity manager layer and not the actual DB engine (Base has no on delete cascade nor foreign key to its children).
So only doctrine can add the logic here because it knows the entity schema. But in this case, when it is deleted from another table, it looks like the special treatment is not triggered.

Comment by Bruno Jacquet [ 06/May/13 ]

Maybe using

cascade={"remove"}

, instead of

onDelete="CASCADE"

to force the cascading process to be handled by doctrine would workaround the bug... But I prefer to have my DB do the logic work as much as possible.

Comment by J [ 25/Apr/14 ]

I've got a similar problem but I have InheritanceType("SINGLE_TABLE") instead of JOINED.
Any updates on when this is getting fixed?





[DDC-3320] [GH-1144] [DDC-3287] Change parent classes of some Events Created: 23/Sep/14  Updated: 19/Oct/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of zebba:

Url: https://github.com/doctrine/doctrine2/pull/1144

Message:

Following my <a href="http://doctrine-project.org/jira/browse/DDC-3287">issue report</a> in Jira find attached the necessary changes.



 Comments   
Comment by Doctrine Bot [ 19/Oct/14 ]

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





[DDC-3251] Segmentation fault in ClassMetadataInfo.php Created: 12/Aug/14  Updated: 20/Oct/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.3
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Kshitij Parajuli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux dev1 3.9.9-302.fc19.x86_64 #1 SMP Sat Jul 6 13:41:07 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

Fedora release 19 (Schrödinger’s Cat)

PHP 5.5.14 (cli) (built: Jul 16 2014 11:41:07)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans

Doctrine Command Line Interface version 2.3.6-DEV



 Description   

I'm seeing a segfault when doing a EntityManager->merge(). Specifically, when on this line in ClassmetadataInfo.php. Details below.

$value = $this->reflFields[$this->identifier[0]]->getValue($entity);

/var/log/messages

Aug 12 08:39:01 dev1 kernel: [62152.629221] php[3539]: segfault at f434172bd1 ip 00007ff432c3aae9 sp 00007fffa060b1b0 error 4 in php[7ff4329e7000+38c000]

strace

--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xc4f1053d11} ---
+++ killed by SIGSEGV ++

gdb backtrace:

(gdb) bt
#0  0x00007f8c8f5ceae9 in zend_std_read_property ()
#1  0x00007f8c8f5b61d7 in zend_read_property ()
#2  0x00007f8c8f4ab66e in zim_reflection_property_getValue ()
#3  0x00007f8c8f59a4ab in dtrace_execute_internal ()
#4  0x00007f8c8abb9a46 in xdebug_execute_internal () from /usr/lib64/php/modules/xdebug.so
#5  0x00007f8c8f65a895 in zend_do_fcall_common_helper_SPEC ()
#6  0x00007f8c8f5d45c8 in execute_ex ()
#7  0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#8  0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#9  0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#10 0x00007f8c8f5d45c8 in execute_ex ()
#11 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#12 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#13 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#14 0x00007f8c8f5d45c8 in execute_ex ()
#15 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#16 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#17 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#18 0x00007f8c8f5d45c8 in execute_ex ()
#19 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#20 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#21 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#22 0x00007f8c8f5d45c8 in execute_ex ()
#23 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#24 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#25 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#26 0x00007f8c8f5d45c8 in execute_ex ()
#27 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#28 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#29 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#30 0x00007f8c8f5d45c8 in execute_ex ()
#31 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#32 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#33 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#34 0x00007f8c8f5d45c8 in execute_ex ()
#35 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#36 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#37 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#38 0x00007f8c8f5d45c8 in execute_ex ()
#39 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#40 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#41 0x00007f8c8f659852 in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER ()
#42 0x00007f8c8f5d45c8 in execute_ex ()
#43 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#44 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#45 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#46 0x00007f8c8f5d45c8 in execute_ex ()
#47 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#48 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#49 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#50 0x00007f8c8f5d45c8 in execute_ex ()
#51 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#52 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
---Type <return> to continue, or q <return> to quit---
#53 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#54 0x00007f8c8f5d45c8 in execute_ex ()
#55 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#56 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#57 0x00007f8c8f659852 in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER ()
#58 0x00007f8c8f5d45c8 in execute_ex ()
#59 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#60 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#61 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#62 0x00007f8c8f5d45c8 in execute_ex ()
#63 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#64 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#65 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#66 0x00007f8c8f5d45c8 in execute_ex ()
#67 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#68 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#69 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#70 0x00007f8c8f5d45c8 in execute_ex ()
#71 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#72 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#73 0x00007f8c8f659852 in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER ()
#74 0x00007f8c8f5d45c8 in execute_ex ()
#75 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#76 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#77 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#78 0x00007f8c8f5d45c8 in execute_ex ()
#79 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#80 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#81 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#82 0x00007f8c8f5d45c8 in execute_ex ()
#83 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#84 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#85 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#86 0x00007f8c8f5d45c8 in execute_ex ()
#87 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#88 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#89 0x00007f8c8f659852 in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER ()
#90 0x00007f8c8f5d45c8 in execute_ex ()
#91 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#92 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#93 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#94 0x00007f8c8f5d45c8 in execute_ex ()
#95 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#96 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#97 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#98 0x00007f8c8f5d45c8 in execute_ex ()
#99 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#100 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#101 0x00007f8c8f65aee0 in zend_do_fcall_common_helper_SPEC ()
#102 0x00007f8c8f5d45c8 in execute_ex ()
#103 0x00007f8c8f59a3a9 in dtrace_execute_ex ()
#104 0x00007f8c8abb8fcc in xdebug_execute_ex () from /usr/lib64/php/modules/xdebug.so
#105 0x00007f8c8f5abed0 in zend_execute_scripts ()
---Type <return> to continue, or q <return> to quit---
#106 0x00007f8c8f54bc65 in php_execute_script ()
#107 0x00007f8c8f65c8a8 in do_cli ()
#108 0x00007f8c8f436420 in main ()

xdebug trace:

   54.4457   16731856                                           -> Tekelec\DVAT\Service\TagService->createTag() /home/vagrant/dvat/library/Tekelec/DVAT/Service/TagService.php:51
   54.4457   16731856                                             -> Doctrine\ORM\EntityManager->merge() /home/vagrant/dvat/library/Tekelec/DVAT/Service/TagService.php:28
   54.4457   16731904                                               -> is_object() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:632
   54.4457   16731856                                               -> Doctrine\ORM\EntityManager->errorIfClosed() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:636
   54.4457   16731856                                               -> Doctrine\ORM\UnitOfWork->merge() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:638
   54.4458   16731992                                                 -> Doctrine\ORM\UnitOfWork->doMerge() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1701
   54.4458   16732136                                                   -> spl_object_hash() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1744
   54.4458   16732448                                                   -> get_class() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1752
   54.4458   16732496                                                   -> Doctrine\ORM\EntityManager->getClassMetadata() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1752
   54.4458   16732496                                                     -> Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:268
   54.4458   16732448                                                   -> Doctrine\ORM\UnitOfWork->getEntityState() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1760
   54.4458   16732496                                                     -> spl_object_hash() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1367
   54.4458   16732400                                                   -> Doctrine\ORM\Mapping\ClassMetadataInfo->getIdentifierValues() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1766
   54.4458   16732448                                                     -> ReflectionProperty->getValue() /home/vagrant/dvat/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:672

The reproducing steps are complicated and require propriety code, but this happens most of the time (80+ percent).

Here is the php bug for this: https://bugs.php.net/bug.php?id=67828



 Comments   
Comment by Marco Pivetta [ 12/Aug/14 ]

Did you try clearing your opcode caches? Is this reproducible in insulated environment?

Comment by Kshitij Parajuli [ 12/Aug/14 ]

Yes, I tried clearing the opcode caches (and clearing proxies and restarting the server). This was also reproducible in multiple servers (one production and one development).

It is not yet reproducible in isolated environment, but I am looking at it. Will update the ticket if I find easy reproducing steps.

Comment by Benjamin Eberlei [ 12/Aug/14 ]

Please try without xdebug, this is enabled according to stacktrace.

Comment by Harold Herrera [ 20/Oct/14 ]

I would like get the Doctrine2-orm, but I get an error in the doctrineORM-2.3.6....tar.gz, could you help me please?.

Comment by Marco Pivetta [ 20/Oct/14 ]

Harold Herrera that is a question unrelated with the issue here.





[DDC-2570] Doctrine CLI Tools - Clear All Cache Created: 24/Jul/13  Updated: 08/Feb/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM, Tools
Affects Version/s: 2.3.4
Fix Version/s: 2.x, 2.5

Type: Improvement Priority: Minor
Reporter: Frederick Marcoux Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Cli, cache, orm


 Description   

It would be nice to be able to clear all cache one shot instead of clearing them one after one...

Like this:

root$ ./doctrine orm:clear-cache:all

Instead of:

root$ ./doctrine orm:clear-cache:metadata
root$ ./doctrine orm:clear-cache:result
root$ ./doctrine orm:clear-cache:query






[DDC-2281] Validation against database-first generated xml requires that the column order within a composite primary key match the order the columns are in in mapping xml Created: 06/Feb/13  Updated: 09/May/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.3.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Aaron Moore Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In using a database-first approach utilizing orm:convert-mapping to generate xml, the validation and schema-tool reports that my composite primary key (ex. Columns A, C, B) be dropped and added in the order in which the mapping appears in the xml (ex. Columns A, B, C).

These columns are not auto-increment and are simply a mixture of int and varchar.



 Comments   
Comment by Benjamin Eberlei [ 09/May/13 ]

Is the composite key a mix of association and field types?

Comment by Aaron Moore [ 09/May/13 ]

I'm trying to remember the usage as it was a short term project but I believe it is.

For example a user has a userid.

The table in question might have a primary key consisting of the userid and an int representing a year..





[DDC-2035] XML Mapping : add attribute "length" for tag "id" Created: 20/Sep/12  Updated: 29/Sep/12

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.2.3
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Minor
Reporter: Erik Müller Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux, Doctrine ORM 2.3.0, MySQL



 Description   

XML mapping :

<id name="id" type="string" length="16"/>

Generate SQL :

id varchar(255) not null

It's not possible with XML mapping to have :

 id varchar(16) not null

Because tag "id" doesn't support "length" attribute.
Please add this attribute



 Comments   
Comment by Fabio B. Silva [ 20/Sep/12 ]

Hi Erik,

The atribute "id" arealdy support "length" in the current doctrine version
: https://github.com/doctrine/doctrine2/blob/2.3/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php#L259

Which version are you using ?





[DDC-1630] Get PersistentCollection::getDeleteDiff is empty when collection changes from 1 item to zero items Created: 31/Jan/12  Updated: 09/Feb/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Lee Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None
Environment:

Symfony2


Attachments: File DDC1630Test.php    

 Comments   
Comment by Steve Müller [ 09/Feb/12 ]

Same problem here. I wanted to write some unit tests, checking the entity relations and ran into exactly the same problem. Maybe my code can provide some more information (Group entity is the owning side, role entity is the inverse side):

WHAT DOES NOT WORK:

        /**
         * Test ArrayCollection
         */
        $group = new Group('Group Test');
        $em->persist($group);
        $em->flush();

        $groups = new ArrayCollection();
        $groups->add($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

        /**
         * Test PersistentCollection
         */
        $em->persist($this->role);
        $em->flush();

        $groups = $this->role->getGroups();
        $groups->removeElement($group); // first remove element before adding a new one

        $group = new Group('Group Test 2');
        $em->persist($group);
        $em->flush();
        $groups->add($group);        

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

WHAT WORKS:

        /**
         * Test ArrayCollection
         */
        $group = new Group('Group Test');
        $em->persist($group);
        $em->flush();

        $groups = new ArrayCollection();
        $groups->add($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

        /**
         * Test PersistentCollection
         */
        $em->persist($this->role);
        $em->flush();

        $groups = $this->role->getGroups();

        $group2 = new Group('Group Test 2');
        $em->persist($group2);
        $em->flush();
        $groups->add($group2);  // first adding a new element before removing one

        $groups->removeElement($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

Hope this helps in any way... I tried figuring it out on my own but I am too drunk right now xD

Comment by Benjamin Eberlei [ 10/Feb/12 ]

Thanks for the report, formatted it

Comment by Benjamin Eberlei [ 10/Feb/12 ]

Which version is that btw?

Comment by Steve Müller [ 16/Feb/12 ]

Occurs in version 2.1.6

Comment by Benjamin Eberlei [ 20/Feb/12 ]

If group is the owning side, why do you only set Role::$groups? This has to be the other way around or not?

Comment by Benjamin Eberlei [ 20/Feb/12 ]

@Steve

I cannot reproduce your issue.

Attached is a test script.

Your code is very weird btw, why are you getting and setting groups collection? It is passed by reference so you can just have something like $role->addGroup() and $role->removeGroup() and encapsulate the logic?

Also your tests are pretty useless, you check if two variables which are the same reference to the same collection are the same. Which should always be true.

@Lee

Can you provide more details? I cant verify this without more details.

Comment by Alexander [ 09/Feb/13 ]

Can anyone provide us with more feedback?





[DDC-1494] Query results are overwritten by previous query. Created: 15/Nov/11  Updated: 09/Feb/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: J Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3 + MySQL 5.5


Attachments: File DDC1494Test.php    

 Description   

I am running a query that JOINs three tables, with a simple WHERE:

$q = $em->createQuery("

SELECT cat, n, c
FROM Project_Model_NoticeCategory cat
JOIN cat.notices n
JOIN n.chapters c
WHERE
c.id = :chapter_id

");

When I do this:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();

$b always has the wrong results. Running the following code:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();
  $z = $q->getArrayResult();

BUG Results: $b != $z (getArrayResult IS CORRECT, it refreshes the results) Note: $a==$b (which is wrong)

Explanation:

There is a chapter table, this has a many-to-many join to notices (these are meta info
about the chapter – a little like tagging a blog post) the notices are grouped into
categories.

Data model:

/**
 * @Entity
 * @Table(name="chapter")
 */
class Project_Model_Chapter
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
 
    /** @Column(type="string") */
    private $title;

	/**
	 * @ManyToMany(targetEntity="Project_Model_Notice", mappedBy="chapters")
	 */
	private $notices;
	
	.... /lots of code snipped/ ....
	
}


/**
 * @Entity
 * @Table(name="notice")
 */
class Project_Model_Notice
{
	/**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
 
    /** @Column(type="string") */
    private $title;
	
	/**
	 * @ManyToMany(targetEntity="Project_Model_Chapter", inversedBy="notices")
	 * @JoinTable(name="chapter_notice")
	 */
	private $chapters;
	
	/**
	 * @ManyToOne(targetEntity="Project_Model_NoticeCategory", inversedBy="notices")
	 */
	private $notice_category;
	
	.... /lots of code snipped/ ....
	
}

/**
 * @Entity
 * @Table(name="notice_category")
 */
class Project_Model_NoticeCategory
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
	/** @Column(type="string") */
    private $title;
	
	/**
	 * Bidirectional - One-To-Many (INVERSE SIDE)
	 *
	 * @OneToMany(targetEntity="Project_Model_Notice", mappedBy="notice_category", cascade={"persist", "remove"})
	 */
	private $notices;

	.... /lots of code snipped/ ....
	
}

Data fixtures:

$tools = new \Project_Model_NoticeCategory;
$tools->setTitle('Tools');
		
$spanner = new \Project_Model_Notice;
$spanner->setTitle('spanner');
$tools->addNotice($spanner);
		
$drill = new \Project_Model_Notice;
$drill->setTitle('power drill');
$tools->addNotice($drill);
		
$this->em->persist($tools);
$this->em->flush();

$tools = new \Project_Model_NoticeCategory;
$tools->setTitle('Safety');
		
$gloves = new \Project_Model_Notice;
$gloves->setTitle('gloves');
$tools->addNotice($gloves);
		
$goggles = new \Project_Model_Notice;
$goggles->setTitle('goggles');
$tools->addNotice($goggles);
		
$this->em->persist($tools);
$this->em->flush();

$chapter1 = new \Project_Model_Chapter;
$chapter1->setTitle('Chapter 1');
$this->em->persist($chapter1);

$chapter2 = new \Project_Model_Chapter;
$chapter2->setTitle('Chapter 2');
$this->em->persist($chapter2);

$chapter1->addNotice($spanner);
$chapter1->addNotice($gloves);

$chapter2->addNotice($spanner);
$chapter2->addNotice($gloves);
$chapter2->addNotice($drill);
$chapter2->addNotice($goggles);

// now persist and flush everything

Initial investigation:

I think it has something to do with HINT_REFRESH ? Stepping through:

ObjectHydrator->_hydrateRow
ObjectHydrator->_getEntity

when it requests the Project_Model_Category from the unit of work, it
seems that the second query is simply grabbing the cached results from
the first results. This MUST be wrong as the second query uses a
different query (the ID changes) and all the results are wrong.



 Comments   
Comment by Benjamin Eberlei [ 15/Nov/11 ]

Fixed formatting

Comment by Benjamin Eberlei [ 18/Nov/11 ]

are you using result caching?

Comment by J [ 21/Nov/11 ]

This is part of my bootstrap
,
,

		
$config = new \Doctrine\ORM\Configuration();
		
$cache = new \Doctrine\Common\Cache\ArrayCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
		
// driver: schema
$driver = $config->newDefaultAnnotationDriver(
	APPLICATION_PATH . '/models'
);
$config->setMetadataDriverImpl($driver);

Comment by Benjamin Eberlei [ 15/Dec/11 ]

Cannot reproduce it with the script attached. Can you try to modify this to fail or write your own testcase?

Comment by Benjamin Eberlei [ 15/Dec/11 ]

Downgraded

Comment by Alexander [ 09/Feb/13 ]

Please provide extra feedback.





[DDC-1370] preInsert, postInsert, prePersist, postPersist, preUpdate, postUpdate code and documentation of events Created: 09/Sep/11  Updated: 26/Feb/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

Type: Improvement Priority: Minor
Reporter: Guilherme Blanco Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Currently we have a set of Lifecycle events, but they seem to be misleading both in actual implementation and documentation.

One good example is prePersist and postPersist, which is only fired when you're creating new entities. It should be renamed to preInsert and postInsert.
As of preUpdate and postUpdate, they seem quite valid.

But if we rename prePersist and postPersist to (pre|post)Insert, we may have a situation where you wanna cover both insert and update.
For this, (pre|post)Persist should be reinstated, but acting differently from what it does currently.



 Comments   
Comment by Rafael Dohms [ 09/Sep/11 ]

Also, documentation for post* methods is broken at the website:

"Changes in here are not relevant to the persistence in the database, but you can use this events to"

It cuts off in mid-sentence.

Comment by Guilherme Blanco [ 09/Dec/11 ]

RDohms, this paragraph was already sorted out.

The actual ticket is still valid here.

Comment by Guilherme Blanco [ 20/Dec/11 ]

Updating fix version

Comment by Matt McNeill [ 26/Feb/14 ]

Commenting here to say that this caused a lot of headaches for our project until we got it sorted out what these events really do.

The problem is that the term 'persist' is ambiguous - it means both persist and update in the context of the persist() function call, but only means INSERT in the context of the event system.





[DDC-987] How to register lifecycle callbacks from YAML is not done correctly in the Events section of the documentation. Created: 14/Jan/11  Updated: 27/Nov/13

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

Type: Documentation Priority: Minor
Reporter: Amir Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html

The above URL has an example of how to register lifecycle callbacks from YAML, but actually it does not work. The correct way of doing it is mentioned on the page: http://www.doctrine-project.org/docs/orm/2.0/en/reference/yaml-mapping.html



 Comments   
Comment by Jeremy Postlethwaite [ 27/Nov/13 ]

Please close this issue

Both pages now have the same documentation.

Doctrine example
  lifecycleCallbacks:
    prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
    postPersist: [ doStuffOnPostPersist ]
Partial stack trace exhibiting call:
/redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php(73) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800 $eventName

prePersist

/redacted-path/src/Application/Modules/System/Entity/Sites.php(161) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800 $args

object(Doctrine\ORM\Event\LifecycleEventArgs)[839]
  private 'objectManager' (Doctrine\Common\Persistence\Event\LifecycleEventArgs) => 
    object(Doctrine\ORM\EntityManager)[330]
      private 'config' => 
        object(Doctrine\ORM\Configuration)[156]

/redacted-path/src/Application/Base.php(371) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800

#0 /redacted-path/src/Application/Modules/System/Entity/Sites.php(161): Application\Base::puke(Object(Doctrine\ORM\Event\LifecycleEventArgs), '/www/sites/loca...', true)
#1 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php(104): Application\Modules\System\Entity\Sites->prePersist(Object(Doctrine\ORM\Event\LifecycleEventArgs))
#2 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(845): Doctrine\ORM\Event\ListenersInvoker->invoke(Object(Doctrine\ORM\Mapping\ClassMetadata), 'prePersist', Object(Application\Modules\System\Entity\Sites), Object(Doctrine\ORM\Event\LifecycleEventArgs), 2)
#3 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1621): Doctrine\ORM\UnitOfWork->persistNew(Object(Doctrine\ORM\Mapping\ClassMetadata), Object(Application\Modules\System\Entity\Sites))
#4 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1577): Doctrine\ORM\UnitOfWork->doPersist(Object(Application\Modules\System\Entity\Sites), Array)
#5 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(624): Doctrine\ORM\UnitOfWork->persist(Object(Application\Modules\System\Entity\Sites))
#6 /redacted-path/src/Application/Modules/Application/Controller/AbstractEntityFormActionController.php(128): Doctrine\ORM\EntityManager->persist(Object(Application\Modules\System\Entity\Sites))

My configuration was slightly different from the example.

  • Changed some of the details to protect the innocent.
My configuration inherited from a mappedSuperclass
  lifecycleCallbacks:
    prePersist: [ prePersist ]
    preFlush: [ preFlush ]




[DDC-1988] Add Any and ManyToAny annotations Created: 18/Aug/12  Updated: 10/Jul/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: Stefano Rodriguez Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

It would be really nice to have @Any and @ManyToAny relations/annotations implemented like on Hibernate.
http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/annotations/ManyToAny.html
Right now I've implemented these in a Symfony2 bundle (that I'd be happy to share once it's ready and a bit documented), using listeners on postLoad, preFlush and prePersist
However I think this is a very common use case that anyone will encounter at least once/twice in every middle/big-sized project, and for this reason I think this should be implemented as a core feature.






[DDC-3285] \Doctrine\ORM\Event\PreUpdateEventArgs::getOldValue and ::getNewValue return wrong values for ManyToMany association Created: 29/Aug/14  Updated: 10/Sep/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Reuben Thompson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux 64 bit, PHP 5.4



 Description   

For most entities the $entityChangeSet[$field] contains an array of
[
0 => old_value
1 => new_value
]
however, for ManyToMany associations it contains a \Doctrine\ORM\PersistentCollection with the current (new) value of the association.

The getOldValue function relies on the other behaviour and simply returns $this->entityChangeSet[$field][0] which will be the first element in the PersistentCollection.

The getNewValue function does likewise but with the second element.

I'd be inclined to alter it to check if $entityChangeSet[$field] instanceof PersistentCollection and return the collection for newValue and throw some kind of Exception for oldValue but don't want to send a patch without checking how you guys would like this to react.



 Comments   
Comment by Reuben Thompson [ 29/Aug/14 ]

I guess this might be related to DDC-3033





[DDC-3308] Cross platform support for DQL "WHERE ... IN" with multiple fields/columns Created: 13/Sep/14  Updated: 14/Sep/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4.2
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Minor
Reporter: Markus Wößner Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql, mysql, sqlite


 Description   

DQL does not support "WHERE ... IN" statements which refer to more than one field.

Example: While

... WHERE e.id IN (1, 2) ...

is valid DQL

... WHERE (e.id, e.name) IN ((1, "amy"), (2, "fred")) ...

is not.

This was discussed some years ago here https://groups.google.com/forum/#!msg/doctrine-user/bE9RfiF4ZGk/vaiEvsX5_rwJ and it appears that it is not SQL-99. Sqlite does not support it, MySQL does.

As http://sqlfiddle.com/#!7/6169b/1 shows it is not a big deal to transform such a query into an equal query which prevents the usage of "WHERE ... IN" constraints at all. I guess the case "pair(a,b) is not unique" can be safely ignored if redundant pairs are skipped on temp table insertion.



 Comments   
Comment by Marco Pivetta [ 14/Sep/14 ]

This looks everything but trivial to me, especially considering that it introduces usage of UNION, which we also do not support because of portability rules.

Comment by Markus Wößner [ 14/Sep/14 ]

As far as I understand the UNION statement would only be needed when doing an "inline table" approach.

Isn't it a usual technique in Doctrine "AST to SQL output walking" to write temp tables?

Comment by Marco Pivetta [ 14/Sep/14 ]

Yes, we use subqueries in a lot of places, but the paginator walkers are already a real mess from a maintenance PoV, so I don't think we want to go down that route.





[DDC-3287] PreUpdateEventArgs need to extend Doctrine\Common\PreUpdateEventArgs Created: 29/Aug/14  Updated: 19/Oct/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: Sebastian Kuhlmann Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, orm


 Description   

Currently the inheritance tree of the EventArgs don't allow for creating event listeners that fit both ORM- and MongoDB-driven applications.

Doctrine\Common defines base classes for Lifecycle event arguments. Doctrine\ORM uses the common library and extends it's classes. So does MongoDB. If you wanted to write something that suits both ORM and MongoDB you should be able to rely on the Common-implementations.

The provided classes to extend:

  • Doctrine\Common\Persistence\Event\LifecycleEventArgs
  • Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs
  • Doctrine\Common\Persistence\Event\ManagerEventArgs
  • Doctrine\Common\Persistence\Event\OnClearEventArgs
  • Doctrine\Common\Persistence\Event\PreUpdateEventArgs

Checking the Github repository there is no common ground for the inheritance mechanism.

  • Doctrine\ORM\Event\LifecycleEventArgs extends Doctrine\Common\Persistence\Event\LifecycleEventArgs
  • Doctrine\ORM\Event\PreUpdateEventArgs extends Doctrine\ORM\Event\LifecycleEventArgs
  • Doctrine\ORM\Event\PreFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\PostFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\OnFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\OnClearEventArgs extends Doctrine\Common\EventArgs

This needs to change and ORM\PreUpdateEventArgs as well as ORM\OnClearEventArgs need to extend the respective events from Doctrine\Common.



 Comments   
Comment by Sebastian Kuhlmann [ 23/Sep/14 ]

See https://github.com/doctrine/doctrine2/pull/1144

Comment by Christophe Coevoet [ 04/Oct/14 ]

All flush event args should be updated to extend ManagerEventArgs (and marking their getEntityManager method as deprecated too)

Comment by Christophe Coevoet [ 04/Oct/14 ]

to be clear, the change on PreUpdateEventArgs cannot be done until 3.0 because of BC

Comment by Doctrine Bot [ 19/Oct/14 ]

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





Generated at Fri Oct 24 15:46:03 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.