All the entities you pasted have only one @ORM\Id, which is the composite
one?

On Mon, Jan 5, 2015 at 4:15 PM, <[email protected]> wrote:

> I use the latest Symfony framework with the included Doctrine bundle.
> Doctrine is at version 2.4.
>
> I have a entity with a composite foreign key that fails to persist,
> because the INSERT-statement only includes half of the foreign key.
>
> The scenario is simple: We have persons and rental units (aka apartments,
> rooms, etc.) that can be rented by persons. There is a many-to-many
> association between persons and rental units with an additional attribute
> "period" that defines the period of time that a person rents a rental unit.
> Hence, this many-to-many relation is broken up into two many-to-one
> relations and into a linking entity "rental unit allocation" that stores
> the period.
>
> Please note, that the type of period is a special PostgreSQL type
> ("daterange"). I wrote my own type class to handle this. The latter works
> fine, no problems here.
>
> So here is my simplified code (a left out all setters and getters as well
> as all unimportant attributes):
> namespace HEK\HEKdbBundle\Entity;
>
> use Doctrine\ORM\Mapping as ORM;
> use Doctrine\Common\Collections\ArrayCollection;
> use HEK\HEKdbBundle\Type\DateRange;
>
> /**
>  * @ORM\Entity
>  * @ORM\Table( name = "person" )
>  */
> class Person extends Entity  {
>
>   public function __construct( $firstName, $lastName, \DateTime $birthday
> = null, Gender $gender = null, Country $country = null ) {
>     $this->id = null;
>     $this->rentalUnitAllocations = new ArrayCollection();
>   }
>
>   /**
>    * @ORM\Id
>    * @ORM\Column( name = "id", type = "integer" )
>    * @ORM\GeneratedValue( strategy = "SEQUENCE" )
>    * @var int
>    */
>   protected $id = null;
>
>   /**
>    * @ORM\OneToMany( targetEntity = "RentalUnitAllocation", mappedBy =
> "person" )
>    * @var Doctrine\Common\Collections\ArrayCollection
>    */
>   protected $rentalUnitAllocations = null;
> }
>
>
> /**
>  * @ORM\Entity
>  * @ORM\Table( name = "rental_unit" )
>  */
> class RentalUnit extends Entity  {
>
>   public function __construct( DateRange $lifetime ) {
>     $this->id = null;
>     $this->lifetime = clone( $lifetime );
>     $this->allocations = new ArrayCollection();
>   }
>
>   /**
>    * @ORM\Id
>    * @ORM\Column( name = "id", type = "integer" )
>    * @ORM\GeneratedValue( strategy = "SEQUENCE" )
>    * @var int
>    */
>   protected $id = null;
>
>   /**
>    * @ORM\Column( name = "lifetime", type = "daterange", nullable = false
> );
>    * @var DateRange
>    */
>   protected $lifetime = null;
>
>   /**
>    * @ORM\OneToMany( targetEntity = "RentalUnitAllocation", mappedBy =
> "rentalUnit" )
>    * @var ArrayCollection
>    */
>   protected $allocations = null;
> }
>
>
> /**
>  * @ORM\Entity()
>  * @ORM\Table( name = "rental_unit_allocation" )
>  */
> class RentalUnitAllocation extends Entity  {
>
>   public function __construct( Person $person, RentalUnit $rentalUnit,
> DateRange $period ) {
>     $this->id = null;
>     $this->person = $person;
>     $this->rentalUnit = $rentalUnit;
>     $this->period = clone( $period );
>   }
>
>   /**
>    * @ORM\Id
>    * @ORM\Column( name = "id", type = "integer" )
>    * @ORM\GeneratedValue( strategy = "SEQUENCE" )
>    * @var int
>    */
>   protected $id = null;
>
>   /**
>    * @ORM\ManyToOne( targetEntity = "Person", inversedBy =
> "rentalUnitAllocations" )
>    * @ORM\JoinColumn( name = "person_id", referencedColumnName = "id",
> nullable = false )
>    * @var Person
>    */
>   protected $person = null;
>
>   /**
>    * @ORM\ManyToOne( targetEntity = "RentalUnit", inversedBy =
> "allocations" )
>    * @ORM\JoinColumns = {
>    *      @ORM\JoinColumn( name = "rental_unit_id", referencedColumnName =
> "id", nullable = false ),
>    *      @ORM\JoinColumn( name = "rental_unit_lifetime",
> referencedColumnName = "lifetime", nullable = false )
>    * }
>    * @var RentalUnit
>    */
>   protected $rentalUnit = null;
>
>   /**
>    * @ORM\Column( name = "period", type = "daterange", nullable = false )
>    * @var DateRange
>    */
>   protected $period = null;
> }
>
> The code to persist a new rental unit allocation looks like
> $em = $this->getDoctrine()->getManager();
> $person = $em->getReference( 'HEKdbBundle:Person', 1 );
> $rentalUnit = $em->getRepository('HEKdbBundle:RentalUnit')->find( 42 );
> $period = new DateRange( '2015-01-01', null );
> $alloc = new RentalUnitAllocation( $person, $rentalUnit, $period );
> $em->persist( $alloc );
> $em->flush();
>
> And the error message is
>
> NotNullConstraintViolationException: An exception occurred while executing
> 'INSERT INTO rental_unit_allocation (id, period, person_id, rental_unit_id)
> VALUES (?, ?, ?, ?)' with params [12, "[ 2015-01-01, infinity )", 1, 42]:
>
> SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column
> "rental_unit_lifetime" violates not-null constraint
>
> The error message from PostgreSQL is correct, because the INSERT statement
> actually lacks the column rental_unit_lifetime column. But why?
>
> --
> You received this message because you are subscribed to the Google Groups
> "doctrine-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/doctrine-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to