3
votes

I'm new to Doctrine and I'm trying to implement the new Embeddables present in Doctrine 2.5.

Simplified code:

<?php namespace Blah;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="test")
 */
class Test {

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

    /**
     * @ORM\Embedded(class="Name")
     * @var Name
     */
    private $name;

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

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

    /**
     * @return Name
     */
    public function getName()
    {
        return $this->name;
    }

}

/**
 * @ORM\Embeddable
 */
class Name {

    /**
     * @ORM\Column(type="string")
     */
    private $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function __toString()
    {
        return $this->value;
    }

}

Seeing the query logs, Doctrine is trying to insert/fetch the column strangely named as name_value instead of name.

What I want is to input a Name type object into Test, have in persisted in the database as a string. When I retrieve the entity, I want name to be of type Name, not string.

I tried using @ORM\Column(type="string") in the entity in the name property, and it kind of works. But instead of a Name type, I get a string when Doctrine fetches the entity.

I also tried settingv*@ORM\Column(type="string", name="name")* in the value object, value property, only to have Doctrine name the field as name_name instead of name_value.

The database schema was created manually. I'm using Laravel and Doctrine using mitchellvanw/laravel-doctrine.

1

1 Answers

9
votes

After posting on Doctrine's mailing list (thanks to Marco Pivetta for pointing the responsible code) I learned that Doctrine prefixes embeddables by design.

To remove the prefixes you have to set columnPrefix=false and name your value appropriately.

The resulting code would be:

<?php namespace Blah;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="test")
 */
class Test {

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

    /**
     * @ORM\Embedded(class="Name", columnPrefix=false)
     * @var Name
     */
    private $name;

    /**
     *
     * @param Name $name
     */
    public function __construct(Name $name)
    {
        $this->name = $name;
    }

    /**
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return Name
     */
    public function getName()
    {
        return $this->name;
    }

}

/**
 * @ORM\Embeddable
 */
class Name {

    /**
     * @ORM\Column(type="string", name="name")
     */
    private $value;

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

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

}

Update:

Doctrine's embeddables documentation was updated to reflect this configuration.