How to right insert or update on same Doctrine2 object

ReynierPM picture ReynierPM · Jun 29, 2015 · Viewed 12.9k times · Source

I have this piece of code:

$entity = $em->getRepository('AppBundle:Representative')->find($soqlObj1['records'][0]['Id']);

if ($entity === null) {
    $entity = new Representative();
    $em->persist($entity);
}

// we set the values from veeva
$entity->setVeevaRepId($soqlObj1['records'][0]['Id']);
$entity->setEmail($soqlObj1['records'][0]['Email']);
...

$em->flush();

And this is part of the entity Representative:

class Representative
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="string", length=45, nullable=false, unique=true)
     * @ORM\GeneratedValue()
     * @Expose()
     */
    protected $veeva_rep_id;

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $display_name;

    /**
     * @var string
     * @ORM\Column(type="string", length=255)
     * @Expose()
     */
    protected $avatar_url = 'https://pdone.s3.amazonaws.com/avatar/default_avatar.png';

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $rep_type = "VEEVA";

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $username;

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $first;

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $last;

    /**
     * @var string
     * @ORM\Column(type="string", length=45, nullable=true)
     * @Expose()
     */
    protected $title;

    /**
     * @var string
     * @ORM\Column(type="text", nullable=true)
     */
    protected $bio;

    /**
     * @var string
     * @ORM\Column(type="string", length=45, nullable=true)
     * @Expose()
     */
    protected $phone;

    /**
     * @var string
     * @ORM\Column(type="string", length=45)
     * @Expose()
     */
    protected $email;

    /**
     * @var bool
     * @ORM\Column(type="boolean")
     * @Expose()
     */
    protected $inactive = false;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime", nullable=true)
     * @Expose()
     */
    protected $lastLoginAt;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime")
     * @Expose()
     */
    protected $lastSyncAt;

    /**
     * @var Territory
     * @ORM\ManyToOne(targetEntity="Territory")
     * @ORM\JoinColumn(name="territories_id", referencedColumnName="veeva_territory_id")
     * @Expose()
     */
    protected $territory;

    /**
     * @var string
     * @ORM\Column(type="string", nullable=true, length=150)
     */
    protected $repTokenId;

    ...
}

There are a few others columns that are required at DB level (nullable = false at entity level), my question: if the object doesn't exists at DB it will be created or update based on the code I wrote or I need to move each required field into conditional? Which is the right way to achieve this? I am trying to do a INSERT|UPDATE based on just one query result

Answer

DonCallisto picture DonCallisto · Jun 29, 2015

If you retrieved object from db, doctrine itself knows if the next operation will be an update or an insert: you don't have to worry about anything

Your answer is a valid one but I would modify it as follows

$entity = $em->getRepository('AppBundle:Representative')->find($soqlObj1['records'][0]['Id']);

if ($entity === null) {
    $entity = new Representative();
}

// we set the values from veeva
$entity->setVeevaRepId($soqlObj1['records'][0]['Id']);
$entity->setEmail($soqlObj1['records'][0]['Email']);

$em->persist($entity);
$em->flush();

As I told you, you don't have to worry about insertion or update, doctrine will do it for you. However, if you need to set certain values only if the object is a new one or if it was fetched from db, just add proper code under $entity === null control