Doctrine2 перемещает неизменяемые поля в отдельный класс

Мне нужно переместить некоторые неизменяемые поля в отдельный класс, но я действительно не хочу использовать "join", потому что мне нужны все данные вместе каждый раз.

Есть ли способ иметь некоторые атрибуты сущности как классы, которые отображаются в одну таблицу?

Что-то вроде:

/**
 * @ORM\Entity
 */
class User {
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    ...

    /**
     * @var Address
     * @ORM\... ??
     */
    protected $address
}

/**
 * @ORM\ValueObject ??
 */
class Address {
    /**
     * @var string
     * @ORM\Column(type="string", name="address_zipcode", length=12)
     */
    protected $zipcode;

    /**
     * @var string
     * @ORM\Column(type="string", name="address_country_iso", length=3)
     */
    protected $countryIso;
    ...
}

И структура таблицы будет:

CREATE TABLE User (
    `id` INT(11) NOT NULL auto_increment,
    `address_zipcode` VARCHAR(12) NOT NULL,
    `address_country_iso` VARCHAR(3) NOT NULL,
    PRIMARY KEY (`id`)
);

Ответ 1

То, о чем вы спрашиваете, называется Value Objects.

Там была открытая проблема Jira DDC-93, чтобы добавить поддержку. Он помечается как "Решено" в версии 2.5, который был только что выпущен в бета-версии.

Ответ 2

Если вы хотите хранить объект без соединения:

/**
 * @ORM\Column(name="adress", type="object")
 */

Он автоматически сериализует/десериализуется в текстовое поле

http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html

И добавьте setter с типом, который вы хотите сохранить

public function setAdress(Address $adress)
{
    $this->adress = $adress;

    return $this;
}

Класс адреса не требует каких-либо аннотаций @ORM

Ответ 3

Это будет так, как будто вы сказали что-то вроде.

Добавьте привязку @PreUpdate и @PostLoad к User.

/**
 * @ORM\Entity
 */
class User {
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    ...

    /**
     * @var Address
     * (NOTE: no @ORM annotation here)
     */
    protected $address

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    protected $addressZipCode;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    protected $addressCountryIso;

    public function setAddress(Address $address)
    {
        $this->address = $address;
    }

    /**
     * @ORM\PreUpdate
     *
     * set $addressZipCode and $addressCountryInfo when this object is to
     * save so that doctrine can easily save these scalar values
     */
    public function extractAddress()
    {
        $this->addressZipCode = $this->address->getZipCode();
        $this->addressCountryIso = $this->address->getAddressCountryIso();
    }

    /**
     * @ORM\PostLoad
     *
     * When the row is hydrated into this class,
     * $address is not set because that isn't mapped.
     * so simply, map it manually
     */
    public function packAddress()
    {
        $this->address = new Address();
        $this->address->setZipCode($this->addressZipCode);
        $this->address->setCountryIs($this->addressCountryIso);
    }
}