Reputation: 3484
Quite a long time since I try to handle many-to many relationships with attribute.
I re-checked the entities, the forms... Everything looks ok. Still get an error :
The relationship is built like this: Book > OneToMany > AuthorBook < ManyToOne < Author
Nested forms allow to create books, from which authors are created with a year attribute..
So far, I'm only trying to record new authors, in order to make them exist before handling a relationship with a book.
Here is my code:
foreach ($book->getAuthorBooks() as $authorBook) {
$AuthorUrlname = $this->mu->generateUrlname( $authorBook->getAuthor()->getFirstname().'-'.$authorBook->getAuthor()->getLastname() );
// If the author does not exist yet, it is added to the database:
$checkAuthor = $this->em->getRepository('cmdMyBundle:Author')->findOneByUrlname($AuthorUrlname);
if ($checkAuthor == null) {
// Author does not exist
$newAuthor = new Author();
$newAuthor->setLastname($authorBook->getAuthor()->getLastname());
$newAuthor->setFirstname($authorBook->getAuthor()->getFirstname());
$newAuthor->setUrlname($AuthorUrlname);
$newAuthor->setCollection($this->collection);
$this->em->persist($newAuthor);
$this->em->flush();
}else{
// Author already exists
}
}// foreach $authorBook
And the error: A new entity was found through the relationship 'cmd\MyBundle\Entity\Book#authorBooks' that was not configured to cascade persist operations for entity: cmd\MyBundle\Entity\authorBook@0000000002571fc4000000002c4ddfaa.
Why is the error related to authorBooks relationship ? My code only tries to record a new author...
Thanks
EDIT_____________
Indeed, I made further tests, and a drastic one with this code :
public function onSuccess(Page $page){
$this->em->flush();
This also generates the same error, as if the error was not due to the form processing code... I validated the orm schema using this method, and so far everything looks good.
I tried to cascade persist the entities :
class AuthorBook
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="cmd\MyBundle\Entity\Author", inversedBy="authorBooks", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $author;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="cmd\MyBundle\Entity\Book", inversedBy="authorBooks", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $book;
--
class Book
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="cmd\MyBundle\Entity\AuthorBook", mappedBy="book", cascade={"persist"})
*/
private $authorBooks;
--
class Author
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="cmd\MyBundle\Entity\AuthorBook", mappedBy="author", cascade={"persist"})
*/
private $authorBooks;
This updates the error message:
Entity of type AuthorBook has identity through a foreign entity Author, however this entity has no ientity itself. You have to call EntityManager#persist() on the related entity and make sure it an identifier was generated before trying to persist 'AuthorBook'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
I understand I need to persist and flush books and authors before AuthorBook. However, I can't flush anything. I even have this error when I don't persist anything.
Upvotes: 1
Views: 1882
Reputation: 31919
There is something wrong with your class AuthorBook
. Remove @ORM\Id
for both $author
and $book
and add a correct id field. You should have had an error message when updating your schema, but in case you didn't:
php app/console doctrine:schema:update --force;
Update AuthorBook
to this:
class AuthorBook
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var integer $id
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="cmd\MyBundle\Entity\Author", inversedBy="authorBooks", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $author;
/**
*
* @ORM\ManyToOne(targetEntity="cmd\MyBundle\Entity\Book", inversedBy="authorBooks", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $book;
Upvotes: 1
Reputation: 509
if you don't have any more column in AuthorBook (only foreign keys) I could try to do a manytomany relationship.
Url: Many-to-Many Doctrine documentation
Upvotes: 0