Vamos a crear una interfaz de administración 1N, con dos entidades. La primera, Uno, y la segunda, Muchos, y configurar un panel de administración para la tabla Uno, que puede afectar a varios elementos de la tabla Muchos. Para darle más interés, añadiremos algunos parámetros adicionales, como campos de marca de tiempo para fechas de sincronización con un SI, y campos primarios que no se llaman ID y no se autoincrementan.
 
        En nuestro caso, tenemos una sincronización con un SI que requiere un campo de marca de tiempo.
Solo crea un campo de tipo datetime
Agrega la anotación de opción {'default': 'CURRENT_TIMESTAMP'}
La siguiente anotación creará un campo Timestamps con el valor predeterminado establecido en CURRENT_TIMESTAMP.
* @ORM\Column(type="datetime", nullable=false, options={"default": "CURRENT_TIMESTAMP"})
* @ORM\Version
Para nombrar la tabla correctamente y crear índices, simplemente añade la siguiente anotación en la cabeza de la clase
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Index;
/**
* @ORM\Entity(repositoryClass="App\Repository\WcoconRepository")
* @Table(name="table_name",indexes={@Index(name="PRIMARY", columns={"champs1", "champs2"})})
*/
Para usar un campo diferente al predeterminado 'id', simplemente añade la siguiente anotación:
/**
* @ORM\Column(type="integer")
* @ORM\Id()
*/
private $numero_dossier;
Una vez realizada la relación, es necesario especificar el id que se utilizará en el mapeo. De lo contrario, habrá un error como:
Nombre de columna id referenciado para relación de App\Entity\Many hacia App\Entity\Uno no existe.
Así que en la entidad 'Muchos', necesitas añadir la relación con el id de la entidad 'Uno'
/**
* @ORM\ManyToOne(targetEntity="App\Entity\One", inversedBy="Ones")
* @ORM\JoinColumn(nullable=false, name="many_id", referencedColumnName="one_id")
*/
private $many_id;
Último punto importante; Para evitar que el objeto tenga un nombre como 'App\Entity\Uno:sdfsdfgsdgmlkpoufsdlkjfsdg' durante la edición, es mejor sobrescribir el método __toString(), para mostrar el nombre del objeto.
En la entidad, simplemente incluye un método:
public function __toString()
{
       return "Nom object ".$this->getName();
}
Una vez hecho esto, solo procede con la migración:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Si es necesario, para regenerar el repositorio a partir de las entidades disponibles simplemente lanza el siguiente comando:
php bin/console make:entity --regenerate
Las entidades no serán modificadas.
 
        
Para probar las relaciones entre entidades, puedes ejecutar el siguiente comando:
php bin/console doctrine:schema:validate
 
        
En esta etapa, todo lo que nos queda por hacer es configurar las interfaces de gestión en el admin, y podemos comenzar a desarrollar la autenticación de front-end.
El primer paso de la interfaz de administración es crear la clase en src/Admin/TableAdmin.php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Sonata\AdminBundle\Form\Type\ModelType;
use Sonata\AdminBundle\Form\Type\ModelListType;
use Sonata\Form\Type\CollectionType;
class OneAdmin extends AbstractAdmin
{
	protected function configureFormFields(FormMapper $formMapper)
	{
		$formMapper->tab('General');
		$formMapper->with('Parametres', ['class' => 'col-md-4']);
		$formMapper->add('name', TextType::class, ['required' => false, 'label'=>'Site internet','attr' => ['placeholder' => '']]);
		$formMapper->end()
		$formMapper->with('Parametres', ['class' => 'col-md-8']);
		$formMapper->add('nomduchampsArrayCollection', EntityType::class, [
		'class' => 'App\Entity\Many',
		'choice_label' => 'nom_du_champs_autre_table',
		'label' => 'champs liste',
		'multiple' => true,
		//'expanded' => true,
		]);
		$formMapper->end()
		$formMapper->end('General');
	}
	protected function configureDatagridFilters(DatagridMapper $datagridMapper)
	{
		$datagridMapper->add('name');
	}
	protected function configureListFields(ListMapper $listMapper)
	{
		$listMapper->addIdentifier('name', null, ['label' => 'Nom']);
	}
	public function prePersist($object)
	{
		$this->preUpdate($object);
	}
	public function preUpdate($object)
	{
		$mapping=$object->getManys()->getMapping();
		$currentManys=$this->createQuery()->getQueryBuilder()->getQuery()->getEntityManager()->getRepository($mapping["targetEntity"])
		->findBy([$mapping["mappedBy"]=>$this->id($object)]);
		$object->setMany($object->getManys(),$currentManys);
	}
	public function setMany($collections,$currentManys)
	{
		foreach ($currentCollections as $w) 
		{
			if(!$collections->contains($w)){
			$w->setCollectionID(null);
			}
		}
		$this->collections= new ArrayCollection();
		foreach ($collections as $collection) {
			$this->addCollections($collections);
		}
	}
}
En la entidad One.php, necesitamos añadir nuestro nuevo método para manejar modificaciones
    public function setMany($manys,$current)
    {
        foreach ($current as $w) {
            if(!$manys->contains($w)){
                $w->setManyField(null);
            }
           
        }
        $this->manys = new ArrayCollection();
        
        foreach ($manys as $m) {
            $this->addMany($m);
        }
    }
Luego registrar el servicio en config/services.yaml
    admin.MaTable:
        class: App\Admin\MaTableAdmin
        arguments: [~, App\Entity\MaTable, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, label: "Table MaTable" }
        public: true