Doctrine 2 – not configured to cascade persist operations for entity
- Joacim
- Člen | 229
Zdravím,
už dva dny mám takový větší problém s Doctrine 2 a nevím si rady.
Pokud se snažím uložit schůzku a použiji
$this->em->persist($meeting);
nahlásí mě to
tuto chybu:
Doctrine\ORM\ORMInvalidArgumentException
A new entity was found through the relationship 'App\Model\Entities\Meeting#created_by' that was not configured to cascade persist operations for entity: App\Model\Entities\User@000000004b72e2f900007f852866c8dc. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Model\Entities\User#__toString()' to get a clue.
pokud přidám v entite meeting ke created_by
, cascade={"persist"}
nahlásí mě to toto
Doctrine\ORM\ORMInvalidArgumentException
A new entity was found through the relationship 'App\Model\Entities\User#role' that was not configured to cascade persist operations for entity: Kdyby\GeneratedProxy\__CG__\App\Model\Entities\AclRole@000000000bd2af5c00007f8518be642e. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Model\Entities\AclRole#__toString()' to get a clue.
a tak stále dokola.
pokud použiji $this->em->merge($meeting);
, schůzka se
uloží.
Bohužel po merge mi vložená entita nevrátí její ID (lastInserId dané
entity co jsem vložil).
Proto potřebuji použít persist. Předtím když jsem měl menší DB schéma jsem vše ukládal přes persist a neměl jsem žádný problém.
Pokud mám entitu která se odkazuje na další entity (Meeting MeetingLog – 1:N) a chci vložit ke schůzce log a ukládám schůzku přes merge, flush a ne persist, flush, tzn vytvořím schůzku novou a hned k ní vytvořím log, nebo k již existující schůzce přidám log a k logu hned přidám soubor.
public function addLog(NS_User $creator, $values) {
$created_by = $creator->identity->entity;
$this->em->clear();
$log = new MeetingLog();
$log->name = $values->name;
$log->description = $values->description;
$log->created = new DateTime();
$log->created_by = $created_by;
$log->meeting = $this->getMeeting($values->mid);
$log->log_type = $this->getMeetingLogType(1);
$this->em->merge($log);
//Add file
if ($values->file_1->name != NULL) {
$file = new MeetingFile();
$file->name = $values->file_1->getName();
$file->revision = 1.0;
$file->size = $values->file_1->getSize();
$file->content_type = $values->file_1->getContentType();
$file->sanitized_name = $values->file_1->getSanitizedName();
$file->created = new DateTime();
$file->meeting = $this->getMeeting($values->mid);
$file->created_by = $created_by;
$file->log = $log;
$this->em->merge($file);
$this->em->flush();
$this->file_facade->addFile('meetings', $values->mid, $values->file_1);
}
// Store data to Db tables
$this->em->flush();
}
Dostanu také: IMG , pokud všude kde mi doctrine hlásí dám
,cascade={"persist"}
(i manytoone) dostanu hlášku IMG mezi User
MeetingLog a MeetingFile mám tyto závislosti DB
Entity
class Meeting extends BaseEntity {
/* ------------------------- Association Mapping ------------------------ */
/**
* Sloupec s asociací na Entitu User (Uživatele, který danou schůzku vytvořil).
* -- 5.1. Many-To-One, Unidirectional
* @ORM\ManyToOne(targetEntity="User", cascade={"persist"})
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $created_by;
/**
* Sloupec s asociací na Entitu MeetingType (Typ Schůzky).
* @ORM\ManyToOne(targetEntity="MeetingType", inversedBy="ac_type")
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
*
*/
protected $type;
/**
* Sloupec s asociací na Entitu MeetingStatus (Stav (status) dané schůzky).
* @ORM\ManyToOne(targetEntity="MeetingStatus", inversedBy="ac_meeting")
* @ORM\JoinColumn(name="status_id", referencedColumnName="id")
*
*/
protected $status;
/**
* Sloupec s asociací na Entitu TmC.
* @ORM\ManyToOne(targetEntity="TmC", inversedBy="ac_meeting_c")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
*
*/
protected $customer;
/**
* Sloupec s asociací M:N na Entitu TmPN přes mapovací tabulku typu M:N (meeting_pn_map) (Všechny PN z TM), k dané schůzce
*
* @ORM\ManyToMany(targetEntity="TmPN")
* @ORM\JoinTable(name="meeting_pn_map",
* joinColumns={@ORM\JoinColumn(name="meeting_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="pn_id", referencedColumnName="id")}
* )
* @ORM\OrderBy({"pn" = "ASC"})
*/
protected $ac_pn;
/**
* Sloupec s asociací M:N na Entitu User přes mapovací tabulku typu M:N (meeting_user_map) všinchni uživatele přizvaní (obeznámení) o dané schůzce
*
* @ORM\ManyToMany(targetEntity="User")
* @ORM\JoinTable(name="meeting_user_map",
* joinColumns={@ORM\JoinColumn(name="meeting_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
* @ORM\OrderBy({"last_name" = "ASC"})
*/
protected $ac_invited;
/**
* Namapovaná vazba schůzky 1:N na tabulku všech souborů k dané schůzce.
* @ORM\OneToMany(targetEntity="MeetingFile", mappedBy="meeting")
* @ORM\OrderBy({"name" = "ASC"})
*/
protected $ac_meeting_file;
/**
* Namapovaná vazba schůzky 1:N na tabulku všech logů k dané schůzce.
* @ORM\OneToMany(targetEntity="MeetingLog", mappedBy="meeting")
* @ORM\OrderBy({"created" = "DESC"})
*/
protected $ac_meeting_log;
/* --------------------------- Entity Methods --------------------------- */
/** Konstruktor s inicializací objektů pro vazby mezi entitami. */
public function __construct() {
parent::__construct();
$this->ac_pn = new ArrayCollection();
$this->ac_invited = new ArrayCollection();
$this->ac_meeting_file = new ArrayCollection();
$this->ac_meeting_log = new ArrayCollection();
}
public function addPartNumber(Tm1PartNumber $pn) {
$this->ac_pn[] = $pn;
}
public function addInvited(App\Model\Entities\User $invited) {
$this->ac_invited[] = $invited;
}
}
class MeetingFile extends BaseEntity {
/* ------------------------- Association Mapping ------------------------ */
/**
* Sloupec s asociací na Entitu Meeting (k jaké schůzce se soubor váže).
* @ORM\ManyToOne(targetEntity="Meeting")
* @ORM\JoinColumn(name="meeting_id", referencedColumnName="id")
*/
protected $meeting;
/**
* Sloupec s asociací na Entitu User (Uživatel, který daný soubor vytvořil)
* -- 5.1. Many-To-One, Unidirectional
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $created_by;
/**
* Sloupec s asociací na Entitu MeetingLog 1:1 (Soubor muže být vázán vždy na jeden log)
*
* @ORM\OneToOne(targetEntity="MeetingLog", inversedBy="file", cascade={"persist"})
* @ORM\JoinColumn(name="log_id", referencedColumnName="id")
*/
protected $log;
}
class MeetingLog extends BaseEntity {
/* ------------------------- Association Mapping ------------------------ */
/**
* Sloupec Typ Logu.
* @ORM\ManyToOne(targetEntity="MeetingLogType", inversedBy="ac_meeting_log")
* @ORM\JoinColumn(name="log_type_id", referencedColumnName="id")
*/
protected $log_type;
/**
* Sloupec s asociací na Entitu User (Uživatel, který daný log vytvořil)
* -- 5.1. Many-To-One, Unidirectional
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $created_by;
/**
* Sloupec s asociací na Entitu Meeting (k jaké schůzce se log váže).
* @ORM\ManyToOne(targetEntity="Meeting", inversedBy="ac_meeting_log")
* @ORM\JoinColumn(name="meeting_id", referencedColumnName="id")
*/
protected $meeting;
}
- Joacim
- Člen | 229
class User extends BaseEntity {
/* ------------------------- Association Mapping ------------------------ */
/**
* Sloupec role uživatele.
* @ORM\ManyToOne(targetEntity="AclRole", inversedBy="ac_user")
* @ORM\JoinColumn(name="role_id", referencedColumnName="id")
*
*/
protected $role;
/**
* Sloupec role uživatele.
* @ORM\ManyToOne(targetEntity="TmRole", inversedBy="ac_user")
* @ORM\JoinColumn(name="tm_role_id", referencedColumnName="id")
*
*/
protected $tm_role;
/**
* Namapovaná vazba uživatele 1:N na tabulku logů příhlášení.
* @ORM\OneToMany(targetEntity="UserLoginInfo", mappedBy="user")
*/
protected $ac_login_info;
/**
* Namapovaná vazba uživatele 1:N na tabulku s nastavením účtu uživatele.
* @ORM\OneToMany(targetEntity="UserAttribute", mappedBy="user")
*/
protected $ac_user_attribute;
/* --------------------------- Entity Methods --------------------------- */
/** Konstruktor s inicializací objektů pro vazby mezi entitami. */
public function __construct() {
parent::__construct();
$this->ac_login_info = new ArrayCollection();
$this->ac_user_attribute = new ArrayCollection();
}
/**
* Přidá informace o uživatelově přihlášení (UserLoginInfo)
* @param \App\Model\Entities\UserLoginInfo $info
*/
public function addLoginInfo(UserLoginInfo $info) {
$this->ac_login_info[] = $info;
$info->user = $this;
}
/**
* Přidá uživatelský atribut (UserAttribute)
* @param \App\Model\Entities\UserAttribute $attribute
*/
public function addUserAttribute(UserAttribute $attribute) {
$this->ac_user_attribute[] = $attribute;
$attribute->user = $this;
}
}
Entita User (přesáhnul jsem u článku max povolený počet znaku 10000), proto komentář.
- David Matějka
- Moderator | 6445
Je problem v tom, ze User-a davas do identity a tam se serializuje a pak unserializuje. To zpusobuje problemy a kdyz nevis, jak s tim spravne zachazet, tak je lepsi se tomu vyhnout.
- Joacim
- Člen | 229
David Matějka napsal(a):
Je problem v tom, ze User-a davas do identity a tam se serializuje a pak unserializuje. To zpusobuje problemy a kdyz nevis, jak s tim spravne zachazet, tak je lepsi se tomu vyhnout.
Stačí tedy dát do Nette User pouze ID z DB a pak si načítat danou entitu a její asociace ? Bohužel je ten projekt tak velký, že používat a implementovat další udělátka nemám čas (min další 2 měsíce), a tohle mě docela solidně zavařilo. Popravdě mě nenapadlo že by zrovna tohle mohlo dělat problémy, hold chybama se člověk učí.
Každopádně nette-identity-doctrine vypadá užitečně a kouknu na něj, ted by mě ale zajímalo jak z této situace ven, zda stačí skutečně do identity dát pouze ID a entitu vyjmout
Editoval Joacim (14. 4. 2016 18:16)
- Joacim
- Člen | 229
Aurielle napsal(a):
Implementace zmíněného rozšíření je práce asi tak na pět minut, zvlášť, když už v identitě svoji entitu User očekáváš.
Ano pravda, včera jsem na to koukal, přesto mě zajímalo zda je problém v tom že jsem ukládal UserEntitu aktuálně přihlášeného uživatele do Nette User → identity->entity, to jsem celé předělal ted mám jen:
Nette\Security\Identity #0208
id private => 1
roles private => array (1)
0 => "admin"
data private => array (3)
email => "admin"
login_id => 103
A přesto dostávám stále stejné hlášky, cache jsem promazal a entitu MeetingLog jsem přidal persist
/**
* Sloupec s asociací na Entitu User (Uživatel, který daný log vytvořil)
* -- 5.1. Many-To-One, Unidirectional
* @ORM\ManyToOne(targetEntity="User", cascade={"persist"})
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $created_by;
a dostanu hlášku
Notice
Undefined index: 000000001c2bade800007f8548f0ec08
// File: .../doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2917
Editoval Joacim (15. 4. 2016 11:10)
- Joacim
- Člen | 229
David Matějka napsal(a):
protoze volas
$this->em->clear();
proc to delas?
moje chyba, to byl pokus o napravu, který jsem u stejné chyby našel na stackowerflow.
Tak jsem přidal cascade persist (k undirectionl asociaci) , odddělal entitu z user identity a místo merge dal persist, oddělal clear a zdá se že už to funguje jak má