I am new to Symfony and I am trying to do a simple Blog. I have users in my database as authors of Comments and 2 types of comments - PostComment and ReplyComment which both extend abstract class Comments. I am trying to save comment to the DB, but I am stuck with this error :
An exception occurred while executing 'INSERT INTO comment (text,
author_id, post_id, comment_type) VALUES (?, ?, ?, ?)' with params
["Lorem ipsum", 1, 1, "post_comment"]:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(blog_symfony.comment, CONSTRAINT FK_9474526CDB1174D2 FOREIGN
KEY (post_comment_id) REFERENCES comment (id))
This is abstract Comment Class :
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
* #ORM\Table(name="comment")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="comment_type", type="string")
* #ORM\DiscriminatorMap({"post_comment" = "PostComment", "reply_comment" = "ReplyComment"})
*/
abstract class Comment
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="userComments")
*/
protected $author;
/**
* #ORM\Column(type="string")
*/
protected $text;
/**
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* #return string $author
*/
public function getAuthor()
{
return $this->author;
}
/**
* #param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* #return string $text
*/
public function getText()
{
return $this->text;
}
/**
* #param string $text
*/
public function setText($text)
{
$this->text = $text;
}
}
This is a post comment class
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\PostCommentRepository")
*/
class PostComment extends Comment
{
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Post", inversedBy="comments")
* #ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/
private $post;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\ReplyComment", mappedBy="postComment", cascade={"remove"}, orphanRemoval=true)
* #ORM\OrderBy({"id"="DESC"})
*/
private $replyComments;
/**
* #return replyComment[] reply comments
*/
public function getReplyComments()
{
return $this->replyComments;
}
/**
* #param replyComment[] reply comments
*/
public function setReplyComments($replyComments)
{
$this->replyComments = $replyComments;
}
/**
* #return Post post
*/
public function getPost()
{
return $this->post;
}
/**
* #param Post post
*/
public function setPost($post)
{
$this->post = $post;
}
}
And finally this is the code in controller runnig logic
if ($postCommentForm->isSubmitted() && $postCommentForm->isValid())
{
/** #var PostComment $comment */
$comment = $postCommentForm->getData();
$comment->setPost($post);
$author = $this->getDoctrine()->getRepository('AppBundle:User')->findOneBy([
'email' => $comment->getAuthor()
]);
$comment->setAuthor($author);
$em = $this->getDoctrine()->getManager();
$em->persist($comment);
$em->flush();
return $this->redirectToRoute("single_post", [
'id' => $post->getId()
]);
}
At first your base class don't need to be abstract. Instead you have to insert this annotation above the class, so doctrine will get it:
#MappedSuperclass()
remove all other doctrine annotations from base entity, all of them belongs to the entity class.
use Doctrine\ORM\Mapping as ORM;
/**
*#MappedSuperclass()
*/
class Comment
{
and entity have all other annotations:
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\PostCommentRepository")
* #ORM\Table(name="comment")
*/
class PostComment extends Comment
{
this should help
Related
I'm trying to save data with ManyToOne relations in a DataFixtures class. And I get this error on saving data.
Please, help me.
Sources:
Entity/DealsCategory.php:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* DealsCategory
*
* #ORM\Table(name="deals_category")
* #ORM\Entity(repositoryClass="AppBundle\Repository\DealsCategoryRepository")
*/
class DealsCategory
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="alias", type="string", length=50, nullable=true)
*/
private $alias;
/**
* #ORM\OneToMany(targetEntity="DealsCategoryLang", mappedBy="category")
*/
protected $categoryLang;
/**
* #return mixed
*/
public function getCategoryLang()
{
return $this->categoryLang;
}
/**
* #param DealsCategoryLang $categoryLang
*/
public function setCategoryLang(DealsCategoryLang $categoryLang = null)
{
$this->categoryLang = $categoryLang;
}
/**
* #param DealsCategoryLang $categoryLang
*/
public function setOneCategoryLang(DealsCategoryLang $categoryLang)
{
$this->categoryLang[] = $categoryLang;
}
/**
* DealsCategory constructor.
*/
public function __construct()
{
$this->categoryLang = new ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set alias
*
* #param string $alias
*
* #return DealsCategory
*/
public function setAlias($alias)
{
$this->alias = $alias;
return $this;
}
/**
* Get alias
*
* #return string
*/
public function getAlias()
{
return $this->alias;
}
}
Entity/DealsCategoryLang.php:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* DealsCategoryLang
*
* #ORM\Table(name="deals_category_lang")
* #ORM\Entity(repositoryClass="AppBundle\Repository\DealsCategoryLangRepository")
*/
class DealsCategoryLang
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="catId", type="integer")
*/
private $catId;
/**
* #var string
*
* #ORM\Column(name="lang", type="string", length=10)
*/
private $lang;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=70)
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="DealsCategory", inversedBy="categoryLang", cascade={"persist"})
* #ORM\JoinColumn(name="catId", referencedColumnName="id")
*
*/
protected $category;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set catId
*
* #param integer $catId
*
* #return DealsCategoryLang
*/
// public function setCatId($catId)
// {
// $this->catId = $catId;
//
// return $this;
// }
/**
* Get catId
*
* #return int
*/
public function getCatId()
{
return $this->catId;
}
/**
* Set lang
*
* #param string $lang
*
* #return DealsCategoryLang
*/
public function setLang($lang)
{
$this->lang = $lang;
return $this;
}
/**
* Get lang
*
* #return string
*/
public function getLang()
{
return $this->lang;
}
/**
* Set title
*
* #param string $title
*
* #return DealsCategoryLang
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
}
DataFixtures/ORM/LoadCategories.php
<?php
namespace AppBundle\DataFixtures\ORM;
use AppBundle\Entity\DealsCategory;
use AppBundle\Entity\DealsCategoryLang;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LoadCategories implements FixtureInterface, ContainerAwareInterface
{
private $container;
/**
* Load data fixtures with the passed EntityManager
*
* #param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
$category = new DealsCategory();
$categoryLang = new DealsCategoryLang();
$categoryLang->setLang('en');
$categoryLang->setTitle('Food and Drinks');
$category->setOneCategoryLang($categoryLang);
$manager->persist($category);
$manager->persist($categoryLang);
$manager->flush();
}
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
I've tried it in different ways, but it's still not working. Tell me please, what i am doing wrong?
UPD:
my errors are:
[Doctrine\DBAL\Exception\NotNullConstraintViolationException]
An exception occurred while executing 'INSERT INTO deals_category_lang (catId, lang, title) VALUES (?, ?, ?)' with params [null, "en", "Food and Drinks"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
I am running the fixtures through the command line:
php bin/console doctrine:fixtures:load --append
Ok, I resolved it...
The problem was in my Fixture class:
Instead of
$category->setOneCategoryLang($categoryLang);
I should put the
$categoryLang->setCategory($category);
,respecting the hierarchy of my entities' relations :(
I'm writing an application using Zend Framework 3. To manage database I decided to use Doctrine. I have two tables pages and pages_meta(something based on wordpress db). They are realted to each other in one-to-many, many-to-one relation. In pages_meta I have key page_id. Now when I try to get meta form Page Entity I got following error:
File: /home/platne/serwer18346/vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php:169
Message: Call to a member function setValue() on null
Now the application code:
Page Entity(removed some code to show important part):
namespace Core\Model;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Page
* #package Core\Model
* #ORM\Entity
* #ORM\Table(name="pages")
*/
class Page
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id")
*/
protected $id;
//other fields definition(here is slug to found by)
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="\Core\Model\PageMeta", mappedBy="pages")
* #ORM\JoinColumn(name="id", referencedColumnName="page_id")
*/
protected $meta;
/**
* Page constructor.
*/
public function __construct()
{
$this->meta = new ArrayCollection();
}
/**
* #return int
*
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $key
* #return ArrayCollection
*/
public function getPageMeta($key = null){
if(!$key) return $this->meta;
return $this->meta->current(); //this is causing the problem tried other functions as well
}
}
PageMeta Entity(same here I removed some code):
namespace Core\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* Class PageMeta
* #package Core\Model
* #ORM\Entity
* #ORM\Table(name="page_meta")
*/
class PageMeta
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id")
*/
protected $id;
/**
* #var int
* #ORM\Column(type="integer", name="page_id")
*/
protected $page_id;
/**
* #var Page
* #ORM\ManyToOne(targetEntity="\Core\Model\Page", inversedBy="page_meta")
* #ORM\JoinColumn(name="page_id", referencedColumnName="id")
*/
protected $page;
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #return int
*/
public function getPageId(): int
{
return $this->page_id;
}
/**
* #param int $page_id
* #return PageMeta
*/
public function setPageId(int $page_id): PageMeta
{
$this->page_id = $page_id;
return $this;
}
//other field definition
/**
* #return Page
*/
public function getPage(){ //this works fine
return $this->page;
}
}
In the controller:
$this->getEntityManager()->getRepository(Page::class);
$page = $pagesTable->findOneBySlug($slug);
//check if page exists
$page->getPageMeta('test'); //this line cause the problem.
Full stack error you can see on page: http://bibliotekadomowa.pl/o-nas
I think it may be an issue with the "mappedBy" param in Page, try changing that to
mappedBy="page"
As it should match the variable name not the table name
Tags Entity :
<?php
namespace App\Entity;
use App\Entity;
use Doctrine\ORM\Mapping;
/**
* #Entity
* #Table(name="tags", options={"collate":"utf8_general_ci", "charset":"utf8", "engine":"MyISAM"})
*/
class Tags extends Entity {
/**
* Many Tags have Many HolidayPackages.
* #ManyToMany(targetEntity="HolidayPackages", mappedBy="tags")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="tid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="hpid", referencedColumnName="id")}
* )
*/
protected $holiday_packages;
/**
* #Column(type="string", length=255)
* #var string
*/
protected $tags;
/**
* #return mixed
*/
public function getHolidayPackages() {
return $this->holiday_packages;
}
/**
* #param mixed $holiday_packages
*/
public function setHolidayPackages($holiday_packages) {
$this->holiday_packages = $holiday_packages;
}
/**
* #return string
*/
public function getTags() {
return $this->tags;
}
/**
* #param string $tags
*/
public function setTags($tags) {
$this->tags = $tags;
}
}
Holiday Packages :
<?php
namespace App\Entity;
use App\Entity;
use Doctrine\ORM\Mapping;
/**
* #Entity
* #Table(name="holiday_packages", options={"collate":"utf8_general_ci", "charset":"utf8", "engine":"MyISAM"})
*/
class HolidayPackages extends Entity {
/**
* Many HolidayPackages have Many Tags.
* #ManyToMany(targetEntity="Tags", inversedBy="holiday_packages")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="hpid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="tid", referencedColumnName="id")}
* )
*/
protected $tags;
/**
* #return mixed
*/
public function getTags() {
return $this->tags;
}
/**
* #param mixed $tags
*/
public function setTags($tags) {
$this->tags = $tags;
}
}
I am trying to create many-to-many assocation mapping. I follow this link :
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html to make this mapping.
But when i try to update doctrine, error occure :
[Doctrine\DBAL\DBALException]
An exception occurred while executing 'ALTER TABLE holiday_tags DROP PRIMARY KEY':
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
orm:schema-tool:update [--complete] [--dump-sql] [--force]
UPDATE
Entity Class :
<?php
namespace App;
use Doctrine\ORM\Mapping as ORM;
/**
* #MappedSuperclass
* #HasLifecycleCallbacks()
*/
abstract class Entity
{
/**
* #var integer
*
* #Column(name="id", type="integer")
* #Id
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="datetime")
* #var \DateTime
*/
protected $created_at;
/**
* #Column(type="datetime", nullable=true)
* #var \DateTime
*/
protected $updated_at;
/**
* Constructor
*/
public function __construct() {
$this->setCreatedAt(new \DateTime());
$this->setUpdatedAt(new \DateTime());
}
/**
* #PreUpdate
*/
public function setUpdatedValue() {
$this->setUpdatedAt(new \DateTime());
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* #param $created_at
*/
public function setCreatedAt($created_at) {
$this->created_at = $created_at;
}
/**
* #return \DateTime
*/
public function getCreatedAt() {
return $this->created_at->format('d/m/Y H:i');
}
/**
* #param $updated_at
*/
public function setUpdatedAt($updated_at) {
$this->updated_at = $updated_at;
}
/**
* #return \DateTime
*/
public function getUpdatedAt() {
return $this->updated_at;
}
}
It creates a class holidaypackages_tags but still give error and i specified name as holiday_tags but it named holidaypackages_tags...
You are trying to create the same table twice "holiday_tags"!
Try this:
class Tags extends Entity {
/**
* Many Tags have Many HolidayPackages.
* #ManyToMany(targetEntity="HolidayPackages", mappedBy="tags")
*/
protected $holiday_packages;
//...
}
class HolidayPackages extends Entity {
/**
* Many HolidayPackages have Many Tags.
* #ManyToMany(targetEntity="Tags", inversedBy="holiday_packages")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="hpid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="tid", referencedColumnName="id")}
* )
*/
protected $tags;
//...
}
Notice that there is no annotation to create the same table again on $holiday_packages field
I don't want to update certain columns for the table.
In the Questions table, I just want to update the question column:
question:
id
question
created_by
created_at
modified_by
modified_at
is_Active
In the above table column, I don't need to update the create_at, created_by, modified_by, modified_at, is_active columns. This is the entity I am using.
Entity:
<?php
namespace Library\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Base class for all the Entities
* This class maps id, active, created and modified columns
*
* #author
*/
/**
* #ORM\MappedSuperclass
*/
class BaseEntity {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id", type="integer")
* #var integer
*/
protected $id;
/**
* #ORM\Column(name="is_active", type="boolean")
* #var boolean
*/
protected $active;
/**
* #ORM\Column(name="created_at", type="datetime")
* #var datetime
*/
protected $createdAt;
/**
* #ORM\Column(name="created_by", type="integer", nullable=true)
* #var integer
*/
protected $createdBy;
/**
* #ORM\Column(name="modified_at", type="datetime")
* #var datetime
*/
protected $modifiedAt;
/**
* #ORM\Column(name="modified_by", type="integer")
* #var integer
*/
protected $modifiedBy;
public function getId() {
return $this->id;
}
public function getActive() {
return $this->active;
}
public function getCreatedAt() {
return $this->createdAt;
}
public function getCreatedBy() {
return $this->createdBy;
}
public function getModifiedAt() {
return $this->modifiedAt;
}
public function getModifiedBy() {
return $this->modifiedBy;
}
public function setId($id) {
$this->id = $id;
}
public function setActive($active) {
$this->active = $active;
}
public function setCreatedAt($createdAt) {
$this->createdAt = $createdAt;
}
public function setCreatedBy($createdBy) {
$this->createdBy = $createdBy;
}
public function setModifiedAt($modifiedAt) {
$this->modifiedAt = $modifiedAt;
}
public function setModifiedBy($modifiedBy) {
$this->modifiedBy = $modifiedBy;
}
}
This is my Question Entity:
<?php
namespace Survey\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Library\Entity\BaseEntity;
use Survey\Entity\Survey;
/**
* Description of Survey Questions
*
* #author Mubarak
*/
/**
* #ORM\Entity
* #ORM\Table(name="survey_questions")
*/
class Question extends BaseEntity{
/**
* #ORM\Column(name="question", type="string")
* #var string
*/
protected $question;
/**
* #ORM\ManyToOne(targetEntity="Survey\Entity\Survey", inversedBy="questions")
* #ORM\JoinColumn(name="survey_id", referencedColumnName="id")
*/
private $surveys;
public function getQuestion() {
return $this->question;
}
public function setQuestion($question) {
$this->question = $question;
}
public function getSurveys() {
return $this->surveys;
}
// public function setSurveys(ArrayCollection $survey) {
public function setSurveys(Survey $surveys = null) {
$this->surveys = $surveys;
}
// public function __toString() {
// return __CLASS__ . ": [id: {$this->id}, name: {$this->name}]";
// }
}
Here is my update function:
public function updateQuestion($userId, $data ) {
try{
$surveyId = 1;
$survey = $this->entityManager->getRepository('Survey\Entity\Survey')->find($surveyId);
$question = new Question();
$question->setQuestion($data['question']);
$question->setSurveys($survey);
$question->setId(1);
$this->entityManager->merge($question);
$this->entityManager->flush();
} catch (Exception $ex) {
throw new Exception("Couldnt update the Question");
}
Below is my error message i am getting:
An exception occurred while executing 'UPDATE survey_questions SET is_active = ?, created_at = ?, created_by = ?, modified_at = ?, modified_by = ? WHERE id = ?' with params [null, null, null, null, null, 1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_at' cannot be null
Here is my insert Operation:
public function insertQuestion($userId, $survey, $questionArr) {
try{
$question = new Question();
$question->setQuestion($questionArr['question']);
$question->setSurveys($survey);
$question->setActive(1);
$question->setCreatedBy($userId);
$question->setCreatedAt($this->createdAt);
$question->setModifiedBy($userId);
$question->setModifiedAt($this->modifiedAt);
$this->entityManager->persist($question);
$this->entityManager->flush();
return $question;
}catch(Exception $ex){
throw new Exception("Couldnt insert the question");
}
}
The problem is that you are creating a new entity, Question.
When calling EntityManager::flush() Doctrine computes the changesets of all the currently managed entities and saves the differences to the database. In case of object properties (#Column(type=”datetime”) or #Column(type=”object”)) these comparisons are always made BY REFERENCE.
"By reference" is important because your new entity has null values for all date time fields (rather than the previously set \DateTime instances). When flush() is called Doctrine correctly detects that these fields are changed and performs the query which fails at the database level.
The merge() operation isn't required in Doctrine when 'editing' entities, these are used for detached instances that need to be managed again.
To solve this you should load the managed instance of the entity first; then modify the fields and flush.
$question = $entityManager->find(1);
$question->setQuestion($data['question']);
$entityManager->flush();
Why my methid setUserId not work?
It's my Post entity:
<?php
// src/Acme/UserBundle/Entity/User.php
namespace Acme\PostBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="posts")
*/
class Post
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
*
* #ORM\Column(type="integer", nullable=false)
*/
public $user_id;
/**
* #ORM\ManyToOne(targetEntity="Acme\PostBundle\Entity\User", inversedBy="posts")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank(message="Введите текст")
* )
*/
protected $text;
/**
* #ORM\Column(type="string", length=255)
*/
protected $address;
/**
*
* #ORM\Column(type="datetime")
*/
protected $date;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user_id
*
* #param integer $userId
* #return Post
*/
public function setUserId($userId)
{
$this->user_id = $userId;
return $this;
}
/**
* Get user_id
*
* #return integer
*/
public function getUserId()
{
return $this->user_id;
}
public function getText()
{
return $this->text;
}
public function __construct() {
$this->date = new \DateTime();
}
//...
}
And my User entity:
<?php
// src/Acme/UserBundle/Entity/User.php
namespace Acme\PostBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
*
* #ORM\Column(type="string")
*/
protected $path;
/**
*
* #ORM\Column(type="string")
*/
protected $username;
/**
* #ORM\OneToMany(targetEntity="Acme\PostBundle\Entity\Post", mappedBy="users")
*/
protected $posts;
public function __construct() {
$this->posts = new ArrayCollection();
}
}
I'm saving in the database via my controller:
public function createAction(Request $request)
{
$post = new Post();
$form = $this->createFormBuilder($post)
->add('text')
->add('address')
->getForm();
$post->setUserId($this->getUser()->getId());
$form->handleRequest($request);
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
}
return $this->redirect($this->generateUrl('home'));
}
And i throw this error:
Integrity constraint violation: 1048 Column 'user_id' cannot be null
Why? My $this->getUser()->getId() is not null, i tried return new Response($this->getUser()->getId()) and get my id
You dont need user_id field because you have user relation on field:
/**
* #ORM\ManyToOne(targetEntity="Acme\PostBundle\Entity\User", inversedBy="posts")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/**
Look in you database, doctrine already created user_id for you.
As the others stated its not possible to set $userId on its own if you have also defined an $user property as entity using the same database column.
Instead change your setters and keep everything else as it is:
class Post
{
// ...
/**
* Set user_id
*
* #param integer $userId
* #throws \Exception
*/
public function setUserId($userId)
{
throw new \Exception('Post->userId can not be set directly');
}
/**
* Set user
*
* #param User $user
* #return Post
*/
public function setUser($user)
{
$this->user = $user;
$this->user_id = $user->getId();
return $this;
}
// ...
}
Now the $userId is automatically updated when you use setUser(...).
Throwing an exception in setUserId helps you preventing bugs in your code. Of course you could also just delete the setter, but it then would be recreated everytime you run another doctrine:generate:entities for your post entity.