Yako
Yako

Reputation: 3484

Flush error in symfony2

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

Answers (2)

Mick
Mick

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

Santi
Santi

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

Related Questions