Marc-Christian Schulze
Marc-Christian Schulze

Reputation: 3254

PHP Doctrine 2 ORM: Non-Entity object as attribute in entity

I'm using Doctrine ORM 2. I got the following entity class.

/**
 * @Entity
 * @Table(name="objects")
 */
class MyObject
{
  /**
   * @Id
   * @GeneratedValue
   * @Column(type="integer")
   */
  private $id;

  /**
   * @var Coordinate
   */
  private $coordinate;
}

class Coordinate
{
   private $x;
   private $y;
   private $z;
}

I want to implement the 3 coordinate values in a separate class for better handling within php. But within the database I want the 3 values to be included in the database table "objects".

Does anyone know how to achieve this?

Best regards

Edit: I found a workaround but it's not the nicest.

    /**
     * 
 * @var integer 
 * @Column(type="integer")
 */
private $x;
/**
 * 
 * @var integer 
 * @Column(type="integer")
 */
private $y;
/**
 * 
 * @var integer 
 * @Column(type="integer")
 */
private $z;

public function getCoordinate()
{
    return new Coordinate($this->x, $this->y, $this->z);
}

public function setCoordinate(Coordinate $coord)
{
    $this->x = $coord->getX();
    $this->y = $coord->getY();
    $this->z = $coord->getZ();
}

Upvotes: 2

Views: 3438

Answers (2)

Gnuffo1
Gnuffo1

Reputation: 3546

The easiest way would be to set that field to use the "object" mapping type.

/**
 * @Column(type="object")
 */
private $coordinate;

Then whatever class of object you put in that field, Doctrine will automatically serialise and unserialise when it is inserted and pulled out of the database.

The other way is to make a custom mapping type - http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html. This uses the same method as the object type, but allows you to specify exactly how the object will be converted between PHP and SQL.

If you used this method had a mapping type named coordinate, you would then just declare this for the field:

/**
 * @Column(type="coordinate")
 */
private $coordinate;

One drawback and as far as I can see there is no way around it, is that you can only use one database column for the field. So you wouldn't be able to order by x, y or z separately using DQL.

Upvotes: 4

Oleg Abrazhaev
Oleg Abrazhaev

Reputation: 2839

Just configure your getter and setter. Like this in your entity

public function setCoordinate (Coordinate $coordinate) {

$coordinateArr = $coordinate->getArrayCopy();

$this->coordinate = serialize($coordinateArr);

}

public function getCoordinate() {

$coordinateArr = unserialize($this->coordinate);

$coordinate = new Coordinate();
$coordinate->exchangeArray($coordinateArr);
return $coordinate;

}

But if you want sql search, you need use LIKE.

Upvotes: 0

Related Questions