Problem
Is there a way that Doctrine recognizes the existing objects when persist with cascade={"persist"}
on a ManyToOne
relation instead and do not fail when trying to insert it again and thus violate the unique key rule?
Description
I am trying to create a Location Entity that can reference a parent to obtain this kind of structure :
To do this, I have the following code on my entity :
/**
* Abstract class representing a location
*
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"COUNTRY" = "CountryLocation", "REGION" = "RegionLocation", "DEPARTMENT" = "DepartmentLocation"})
* @ORM\Table(name="ss_locations")
*
* @package Locations
*/
abstract class ALocation {
/**
* A type that determines the location type
*/
protected ?string $type = null;
/**
* The location ID
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer", options={"unsigned"=true})
*
* @var int
*/
protected int $id;
/**
* The location's slug identifier
*
* @ORM\Column(type="string")
*
* @example "Pays de la Loire" region's slug will be "pays-de-la-loire"
*
* @var string
*/
protected string $slug;
/**
* The location path through its parent's slugs
*
* @ORM\Column(type="string", unique=true)
*
* @example "Loire-Atlantique" department's path would be "france/pays-de-la-loire/loire-atlantique"
*
* @var string
*/
protected string $path;
/**
* The name location's
*
* @ORM\Column(type="string")
*
* @var string
*/
protected string $name;
/**
* The parent location instance
*
* @ORM\ManyToOne(targetEntity="ALocation", cascade={"persist"})
* @ORM\JoinColumn(name="parent", referencedColumnName="id")
*
* @var ALocation|null
*/
protected ?ALocation $parent = null;
// ...
}
// Example of child class
/**
* Class DepartmentLocation
*
* @ORM\Entity
*
* @package Locations
*/
class DepartmentLocation extends ALocation {
const TYPE = "DEPARTMENT";
/**
* @inheritdoc
*/
protected ?string $type = "DEPARTMENT";
// ...
}
The table creation goes well, but when I try to persist one location I got these errors :
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'FR' for key 'PRIMARY')
Warning: Île-de-France cannot be inserted in DB : reason(An exception occurred while executing 'INSERT INTO ss_locations (iso_code, name, parent_id, type) VALUES (?, ?, ?, ?)' with params ["FR", "France", null, "COUNTRY"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'FR' for key 'PRIMARY')
Warning: Paris cannot be inserted in DB : reason(An exception occurred while executing 'INSERT INTO ss_locations (iso_code, name, parent_id, type) VALUES (?, ?, ?, ?)' with params ["FR", "France", null, "COUNTRY"]:
Here is an example of the Database content wanted
And here is how I try to persist it :
// ...
foreach ( $locations as $location ) :
try {
DoctrineEntityManager::get()->persist($location);
DoctrineEntityManager::get()->flush();
} catch ( Throwable $e ) {}
}
// ...