1

I have Entity provider (it is just entity repository which searches and gives me a user while authentication) like this entity provider (MyBundle:Employee implements UserInterface so that`s ok)

class EmployeeRepository extends EntityRepository implements UserProviderInterface
{
   public function loadUserByUsername($username)
   {
       $user = $this->getEntityManager()
        ->createQuery("SELECT e FROM MyBundle:Employee e ...")
        ->setParameters(...)->getOneOrNullResult();
        if ($user) {
            return $user;
        }

        throw new UsernameNotFoundException();
    }

    public function refreshUser(UserInterface $user)
    {
        ...

       return $this->find($user->getId());
    }
}

and I have another entity like

class Task {
    ...

    /**
     * @ManyToOne(targetEntity="Employee")
     * @JoinColumn()
     */
    protected $creator;

    ... + setters/getters
}

so somewhere in controller i have:

$task = new Task();
$task->setCreator($this->getUser()) // or $this->get('security.context')->getToken()->getUser();
$em->persist($task);
$em->flush();

and I have exception "A new entity was found through the relationship '...\Entity\Task#creator' that was not configured to cascade persist operations for entity: ...\Entity\Employee@0000000066a194ca0000000038e61044. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist"

but how can it be: unpersisted entity was given by entityRepository ??? (if persist getUser() em tries to insert new Employee) How can I set creator of task?

jhard
  • 127
  • 1
  • 11

3 Answers3

1

As I understand, you want to be able to join the Employee entity on Task entity in order to know which user has created the Task.

If so, you should probably take a look at the StofDoctrineExtensionBundle that allows you to easily use DoctrineExtension in Symfony2.

DoctrineExtension provides a blameable behavior:

Blameable behavior will automate the update of username or user reference fields on your Entities or Documents. It works through annotations and can update fields on creation, update or even on specific property value change.

namespace Entity;

use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Article
{
    // ...

    /**
     * @var string $createdBy
     *
     * @Gedmo\Blameable(on="create")
     * @ORM\Column(type="string")
     */
    private $createdBy;

    /**
     * @var string $updatedBy
     *
     * @Gedmo\Blameable(on="update")
     * @ORM\Column(type="string")
     */
    private $updatedBy;

    // ...

    public function getCreated()
    {
        return $this->created;
    }

    public function getUpdated()
    {
        return $this->updated;
    }
}

Hope this helps

Picoss
  • 2,047
  • 13
  • 14
1

I found the solution.

in this code I used new instance of entity manager like $this->get('doctrine.orm.entity_manager')

$task = new Task();
$task->setCreator($this->getUser())
$em->persist($task);
$em->flush();

, so new entity manager knows nothing about entities such as User

and the solution was to use default entity manager

$em = $this->get('doctrine.orm.default_entity_manager');
...
$em->persist(task);
$em->flush();

works fine.

jhard
  • 127
  • 1
  • 11
0

I can't see al the code, but if you want to insert new task and new user in the same time (using collection type in forms) you need to define it in your entity (cascade annotation):

class Task {
    ...

    /**
     * @ManyToOne(targetEntity="Employee", cascade={"persist"})
     * @JoinColumn()
     */
    protected $creator;

    ... + setters/getters
}


For more info about cascade operations see Doctrine documentation: http://docs.doctrine-project.org/en/2.0.x/reference/working-with-associations.html#transitive-persistence-cascade-operations

123dcck
  • 236
  • 1
  • 4
  • 18