Reputation: 39
I am completely desperate !! I ask for your help! it's been almost two weeks now that I block on this point and I do not sleep almost at night :-(
the context:
Symfony 3.4 vich-uploder "^ 1.4"
I get this exception:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'document_name' cannot be null
I explain my problem:
-I have a OneToOne relationship between 2 entities (NoteFrais and Justificatif).
- Each NoteFrais has one Justificatif.
- Justificatif is a vichUplodable file.
- Everything works perfectly on my local environment.
- The problem arises only on my version in production on server.
In this same project, I already have other mapping vich_uploader for other relations between other entities. Everything works perfectly for them.
Here is my configuration:
parameters:
locale: fr
app.path.logos: /uploads/logos
app.path.imports: /uploads/imports
app.path.documents: /uploads/documents
vich_uploader:
db_driver: orm
mappings:
logo:
uri_prefix: '%app.path.logos%'
upload_destination: '%kernel.root_dir%/../web%app.path.logos%'
namer: vich_uploader.namer_uniqid
inject_on_load: false
delete_on_update: true
delete_on_remove: true
import:
uri_prefix: '%app.path.imports%'
upload_destination: '%kernel.root_dir%/../web%app.path.imports%'
namer: vich_uploader.namer_uniqid
inject_on_load: false
delete_on_update: true
delete_on_remove: true
document:
uri_prefix: '%app.path.documents%'
upload_destination: '%kernel.root_dir%/../web%app.path.documents%'
namer: vich_uploader.namer_uniqid
inject_on_load: false
delete_on_update: true
delete_on_remove: true
I have no problem with the first 2 mappings (logo and import) in both local environment and prod server.
Here is Justificatif entity(@vich/uploadable)
**
* Justificatif
*
* @ORM\Table(name="justificatif")
* @ORM\Entity(repositoryClass="MKG\MystiBundle\Repository\JustificatifRepository")
* @vich\Uploadable
*/
class Justificatif
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="document", fileNameProperty="documentName")
*
* @var File
*/
private $justificatifFile;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $documentName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime
*/
private $updatedAt;
/**
* Constructor
*/
public function __construct()
{
$this->updatedAt = new \DateTime();
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|UploadedFile $justificatif
*/
public function setJustificatifFile(File $justificatif = null)
{
$this->justificatifFile = $justificatif;
if ($justificatif) {
$this->updatedAt = new \DateTime('now');
}
}
/**
* @return File|null
*/
public function getJustificatifFile()
{
return $this->justificatifFile;
}
/**
*
* @param $documentName
*
* @return $this
*/
public function setDocumentName($documentName)
{
$this->documentName = $documentName;
return $this;
}
/**
* @return string|null
*/
public function getDocumentName()
{
return $this->documentName;
}
/**
* Set updatedAt
*
* @param \DateTime $updatedAt
*
* @return Justificatif
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
}
Here is NoteFrais Entity(with a relation):
/**
* NoteFrais
*
* @ORM\Table(name="note_frais")
* @ORM\Entity(repositoryClass="MKG\MystiBundle\Repository\NoteFraisRepository")
* @Vich\Uploadable
*/
class NoteFrais
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="MKG\MystiBundle\Entity\Mission", cascade={"persist"})
* @ORM\JoinColumn(name="mission_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
*/
private $mission;
/**
* @ORM\ManyToOne(targetEntity="MKG\MystiBundle\Entity\CodeComptable", cascade={"persist"})
* @ORM\JoinColumn(name="compte_comptable_id", referencedColumnName="id", onDelete="SET NULL", nullable=true)
*/
private $compteComptable;
/**
* @var string
*
* @ORM\Column(name="montant_defraiement_max", type="string", length=255, nullable=false)
*/
private $montantDefraiementMax;
/**
* @var string
*
* @ORM\Column(name="refacturation_client", type="string", length=255, nullable=true)
*/
private $refacturationClient;
/**
* @var string
*
* @ORM\Column(name="total_defraiement", type="string", length=255, nullable=true)
*/
private $totalDefraiement;
/**
* @var string
*
* @ORM\Column(name="total_refacturation", type="string", length=255, nullable=true)
*/
private $totalRefacturation;
/**
* @var string
*
* @ORM\Column(name="compte_avances_et_acomptes", type="string", length=255, nullable=true)
*/
private $compteAvancesEtAcomptes;
/**
* @var string
*
* @ORM\Column(name="admin_current_user", type="string", length=255, nullable=true)
*/
private $currentUser;
/**
* @var string
*
* @ORM\Column(name="code_affaire", type="string", length=255, nullable=true)
*/
private $codeAffaire;
/**
* @var string
*
* @ORM\Column(name="etat", type="string", length=255, nullable=true)
*/
private $etat;
/**
* @ORM\OneToOne(targetEntity="Justificatif", cascade={"persist"})
* @ORM\JoinColumn(name="justificatif_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
*/
private $justificatif;
/**
* @var \DateTime
*
* @ORM\Column(name="dateCreation", type="datetime")
*/
private $dateCreation;
public function __construct() {
$this->dateCreation = new \DateTime;
$this->etat = "0";
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
//======== Getters et Setters ========//
/**
* Set justificatif
*
* @param \MKG\MystiBundle\Entity\Justificatif $justificatif
*
* @return NoteFrais
*/
public function setJustificatif(\MKG\MystiBundle\Entity\Justificatif $justificatif = null)
{
$this->justificatif = $justificatif;
return $this;
}
/**
* @return \MKG\MystiBundle\Entity\Justificatif
*/
public function getJustificatif()
{
return $this->justificatif;
}
//======== Getters et Setters ========//
}
Justificatif form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('justificatifFile', FileType::class, array(
//'data_class' => null,
'label' => false,
'required' => true,
'attr' => array(
'class' => 'NoteFraisBootstrapFileInput',
'type' => 'file',
'placeholder' => 'Selectionner un justificatif (jpeg, png, jpg, pdf)',
'data-preview-file-type' => 'text',
'data-allowed-file-extensions' => '["jpeg", "png", "jpg", "pdf"]',
)
));
}
I use the FileType instead of VichType is it works perfectly usually, so the problem does not come from there ...
Here is NoteFrais Form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//->add('circuit')
//======Autres champs======//
->add('justificatif', JustificatifType::class, array(
'required' => false));
}
I tried a lot of things, revised my code, read pages and pages of forum ...
For information:
-I have the right rights on the destination folders on the server.
-I have tried several times to change the name of the problematic mapping ...
- I cleaned the cache so much (acquired, ordered ...)
On the other hand:
I noticed that I'm pointing my Justificatif entity to another existing mapping, everything works perfectly ??? Awesome ... But that's not what I want ... I want to keep 3 different matches and I want to understand why this 3rd mapping is ignored.
Thank you to those who gave me time. :-)
Upvotes: 1
Views: 205
Reputation: 39
I have finally solved this problem! In fact, it was very stupid ... The problem only concerns the prod environment, which means that the configuration used must be registered from the config_prod.yml file and it was not my case! Most of the time, i am in dev environment , so I ended to ignoring the existence of this file ... Thank you to everyone who tried to help me!
Upvotes: 0
Reputation: 650
In relations, you have to add the other form as EntityType in your form Builder. If OneToOne as EntityType and OneToMany as CollectionType.
->add('justificatif', EntityType::class, array(
'class' => 'YourBundle:Justificatif',
'required' => false
));
you can also add nullable true to your attribute $documentName in Justificatif Entity, to avoid problems with empty values inserted.
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var string
*/
private $documentName;
EDITED Indeed, the field is not persisted, it has to be annotated as File in the attribute entity. You can use Vich\UploaderBundle\Entity\File embeddable for storing file info in your ORM entity
In your class Justificatif
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="document", fileNameProperty="document.name")
*
* @var File
*/
private $justificatifFile;
/**
* @ORM\Embedded(class="Vich\UploaderBundle\Entity\File")
*
* @var EmbeddedFile
*/
private $fileJustificatif;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|UploadedFile $justificatifFile
*/
public function setjustificatifFile(?File $justificatifFile = null)
{
$this->justificatifFile = $justificatifFile;
if (null !== $justificatifFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getjustificatifFile(): ?File
{
return $this->justificatifFile;
}
From the documentation https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md
Upvotes: 0