I have the following User entity and fixture file, but when I run app/console doctrine:fixtures:load I get the following error and not sure why. If I remove the date fields the fixtures generate fine. What am I missing here? Thanks.
The error: Could not determine how to assign created_at to a AppBundle\Entity\User object
<?php
namespace AppBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
*/
class User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=255)
*/
private $role;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="phone", type="string", length=16)
*/
private $phone;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created_at", type="datetime", nullable=true)
*/
private $createdAt;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated_at", type="datetime", nullable=true)
*/
private $updatedAt;
And my fixture yml:
AppBundle\Entity\User:
user{1..10}:
name: <firstName()> <lastName()>
role: employee
email: <email()>
phone: <numberBetween(1555000000, 1555999999)>
created_at: <datetimeBetween('-5 days', 'now')>
updated_at: <datetimeBetween('-5 days', 'now')>
Not sure, but I believe that the naming is not correct, just what the error is saying. I think it should be:
createdAt: <datetimeBetween('-5 days', 'now')>
updatedAt: <datetimeBetween('-5 days', 'now')>
I am afraid you can't set timestampable fields manually. In documentation and entity example there are no setters at all for such fields. So in fixtures you can simply remove created_at and updated_at (they will be set automatically):
ppBundle\Entity\User:
user{1..10}:
name: <firstName()> <lastName()>
role: employee
email: <email()>
phone: <numberBetween(1555000000, 1555999999)>
Related
I'm creating an REST api with Symfony 4.2 and Doctrine as ORM connected to a MySQL database. I receive data in JSON , deserialize them with JMSSerializer and use the doctrine merge function to attach it. How can I merge the entity I got from the JSON with an already existing entity, updating only the given fields in the JSON?
Event entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Type;
/**
* Event
*
* #ORM\Table(name="Event", indexes={#ORM\Index(name="Organiser", columns={"Organiser"})})
* #ORM\Entity
*/
class Event
{
/**
* #var int
*
* #ORM\Column(name="ID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue
* #Type("int")
*/
private $id;
/**
* #var \Invited
*
* #ORM\OneToMany(targetEntity="Invited",mappedBy="event",cascade={"persist","merge","remove"})
* #Type("ArrayCollection<App\Entity\Invited>")
*/
private $guests;
/**
* #var string
*
* #ORM\Column(name="Title", type="string", length=255, nullable=false)
* #Type("string")
*/
private $title;
/**
* #var \DateTime
*
* #ORM\Column(name="StartDate", type="datetime", nullable=false)
* #Type("DateTime")
*/
private $startdate;
/**
* #var \DateTime|null
*
* #ORM\Column(name="EndDate", type="datetime", nullable=true)
* #Type("DateTime")
*/
private $enddate;
/**
* #var string
*
* #ORM\Column(name="Place", type="string", length=255, nullable=false)
* #Type("string")
*/
private $place;
/**
* #var string|null
*
* #ORM\Column(name="ImagePath", type="string", length=255, nullable=true)
* #Type("string")
*/
private $imagepath;
/**
* #var \User
*
* #ORM\ManyToOne(targetEntity="User",cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Organiser", referencedColumnName="ID")
* })
* #Type("App\Entity\User")
*/
private $organiser;
?>
Deserialisation
$json = $request->getContent();
$serializer = SerializerBuilder::create()->build();
$event = $serializer->deserialize($json,'App\Entity\Event','json');
Merging
$feedback = $this->em->merge($newEvent);
$this->em->flush();
Expected vs Actual results:
If I have an already existing and attached event like:
{
id:1,
title: 'oldTitle',
startDate: oldDate,
place: 'oldPlace',
...
}
And I receive :
{
id:1,
title: 'newTitle'
}
Expected result:
{
id:1,
title: 'newTitle',
startDate: oldDate,
place: 'oldPlace',
...
}
Actual result when looking to the database:
{
id:1,
title: 'newTitle',
startDate: null,
place: null,
...
}
How can I achieve that in a efficient way?
I am using Symfony 3 and want to map Entity Userto have many BitcoinWallet
My AppBundle\Entity\User.php looks like that:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $firstName;
/**
* #var string
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $lastName;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Assert\File(maxSize="2048k")
* #Assert\Image(mimeTypesMessage="Please upload a valid image.")
*/
protected $profilePicture;
/**
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
* )
*/
protected $email;
protected $emailCanonical;
/**
* #ORM\ManyToOne(targetEntity="BitcoinBundle\Entity\BitcoinWallet")
* #ORM\JoinColumn(name="bitcoin_wallet", referencedColumnName="id")
*/
protected $bitcoinWallet;
/**
* #var \DateTime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var \DateTime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated;
My BitcoinBundle\Entity\BitcoinWallet is below:
<?php
namespace BitcoinBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="BitcoinBundle\Entity\BitcoinWalletRepository")
* #ORM\Table(name="bitcoin_wallet")
* #ORM\HasLifecycleCallbacks
*/
class BitcoinWallet
{
/**
* in use = The address is being used for some reason
* available = the address is free
*/
const STATE_IN_USE = 0;
const STATE_AVAILABLE = 1;
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\Column(type="string", length=34, unique=true)
*/
private $address;
/**
* #ORM\Column(name="state", type="smallint")
*/
private $state;
/**
* #ORM\Column(name="balance", type="decimal", precision=16, scale=8)
*/
private $balance = 0;
/**
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updated_at;
After I run php bin/console doctrine:schema:update --force database was updated successfully, but now I am getting this message:
The target-entity BitcoinBundle\Entity\BitcoinWallet cannot be found in 'AppBundle\Entity\User#bitcoinWallet'.
It looks like entity declaration was incorrect.
In BitcoinBundle\Entity\BitcoinWallet should be ManyToOne statment:
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\User", inversedBy="bitcoin_wallet")
*/
protected $id;
And ManyToOne statment in AppBundle\Entity\User.php is wrong one.
Hello guys i'm newbie on Symfony and making a web using sonata admin bundle. I wanted to add event on adesigns calendar bundle from sonata admin but when i extend EventEntity class and try to add new event, it gave me below error:
Type error: Argument 2 passed to
AppBundle\Entity\Schedule::__construct() must be an instance of
DateTime, none given, called in /path/to/project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php
on line 509
I know it causes type of DateTime, but i don't know how to solve it.
Here's the extended code:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use ADesigns\CalendarBundle\Entity\EventEntity;
/**
* Schedule
*
* #ORM\Table(name="schedule")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ScheduleRepository")
*/
class Schedule extends EventEntity {
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="title", type="string", length=255)
*/
protected $title;
/**
* #var string
* #ORM\Column(name="url", type="string", length=255, nullable=true)
*/
protected $url;
/**
* #var string
* #ORM\Column(name="bgColor", type="string", length=255)
*/
protected $bgColor;
/**
* #var string
* #ORM\Column(name="fgColor", type="string", length=255)
*/
protected $fgColor;
/**
* #var string
* #ORM\Column(name="cssClass", type="string", length=255, nullable=true)
*/
protected $cssClass;
/**
* #var bool
* #ORM\Column(name="allDay", type="boolean")
*/
protected $allDay;
/**
* #var DateTime
* #ORM\Column(name="startDatetime", type="datetime")
*/
protected $startDatetime;
/**
* #var DateTime
* #ORM\Column(name="endDatetime", type="datetime")
*/
protected $endDatetime;
public function __construct($title, \DateTime $startDatetime, \DateTime $endDatetime = null, $allDay = false, $hall) {
parent::__construct($title, $startDatetime, $endDatetime, $allDay);
$this->hall = $hall;
}
/**
* Get id
*
* #return int
*/
public function getId() {
return $this->id;
}
}
If you try to extend a Doctrine entity not designed for that you will encounter problems.
You should use an event listener or a subscriber class instead.
I'm using this query builder in my repository:
public function findByCityCategory($city, $category)
{
$qb = $this->createQueryBuilder('e')
->select(['e.id','e.title','e.address', 'e.lat', 'e.lng', 'e.siteUrl', 'e.phoneNo', 'w', 'd.id as category', 'avg(r.rating) as rating'])
->innerJoin('e.workingTimes', 'w')
->innerJoin('e.category', 'd')
->where('d.id = :categoryId')
->andWhere('e.city = :cityId')
->leftJoin('e.ratings', 'r')
->groupBy('r.place')
->setParameter('categoryId', $category)
->setParameter('cityId', $city);
return $qb->getQuery()->getResult();
}
But when I try to execute it, I get:
"message": "[Semantical Error] line 0, col -1 near 'SELECT e.id,': Error: Cannot select entity through identification variables without choosing at least one root entity alias.",
"class": "Doctrine\\ORM\\Query\\QueryException",
I looked for similar problems here and here but none of these worked for me. My Entities looks like that:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Place
*
* #ORM\Table(name="place")
* #ORM\Entity(repositoryClass="AppBundle\Repository\PlaceRepository")
*/
class Place
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
* #Assert\NotBlank()
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #var float
* #Assert\NotBlank()
* #ORM\Column(name="lat", type="float")
*/
private $lat;
/**
* #var float
* #Assert\NotBlank()
* #ORM\Column(name="lng", type="float")
*/
private $lng;
/**
* #var string
*
* #ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="fb_page", type="string", length=255, nullable=true)
*/
private $fbPage;
/**
* #Assert\NotBlank()
* #ORM\ManyToOne(targetEntity="City")
* #ORM\JoinColumn(name="city_id", referencedColumnName="id")
*/
private $city;
/**
* #Assert\NotBlank()
* #ORM\ManyToOne(targetEntity="Category", inversedBy="places")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $category;
/**
* #var string
*
* #ORM\Column(name="site_url", type="string", length=255, nullable=true)
*/
private $siteUrl;
/**
* #ORM\ManyToMany(targetEntity="WorkingTime", cascade={"persist"})
* #ORM\JoinTable(name="places_workingtimes",
* joinColumns={#ORM\JoinColumn(name="place_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="workingtime_id", referencedColumnName="id", unique=true)}
* )
*/
private $workingTimes;
/**
* #var string
* #ORM\Column(name="phone_no", type="string", length=255, nullable=true)
*
*/
private $phoneNo;
/**
* #ORM\OneToMany(targetEntity="Rating", mappedBy="place")
*/
private $ratings;
}
`
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Rating
*
* #ORM\Table(name="rating")
* #ORM\Entity(repositoryClass="AppBundle\Repository\RatingRepository")
*/
class Rating
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="rating", type="smallint")
*/
private $rating;
/**
* #ORM\ManyToOne(targetEntity="Place", inversedBy="ratings")
* #ORM\JoinColumn(name="place_id", referencedColumnName="id")
*/
private $place;
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
This error only occurs, when I try to select 'w'. So, how can I join this collection of objects?
If you want to only get partial fields from your entity, you have to use the PARTIAL keyword as explained on documentation: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/partial-objects.html
It would be better to load all the fields instead of some if you use the ORM query builder, because the ORM is made to work with objects. If you need only few fields, it can be a better practice to use the native SQL query builder.
I've managed to do it by excluding unnecessary fields from Place entity using JMS Serializer's Exclude() annotation instead of selecting required fields from entity.
I know this seems like a very basic question but PLEASE before voting down, read until the end.
This question came to my mind when using Codeigniter along with Doctrine 2.
I have noticed that, at least when using annotation, the synthax is slightly different than when using Doctrine 2 with Symfony2 and I am wondering why.
I'll provide an example:
This is a class in Symfony2 with a Many To One relation:
<?php
namespace Pondip\LakeBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* Lake
*
* #ORM\Table(name="pondip_lake")
* #ORM\Entity(repositoryClass="Pondip\LakeBundle\Entity\LakeRepository")
*/
class Lake
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
* #Assert\Type(type="Pondip\LakeBundle\Entity\Venue")
*
* #ORM\ManyToOne(targetEntity="Pondip\LakeBundle\Entity\Venue")
* #ORM\JoinColumn(name="venue_id", referencedColumnName="id")
*/
private $venue;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var text
*
* #ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Pondip\UserAccountBundle\Entity\User")
* #ORM\JoinColumn(name="created_by", referencedColumnName="id", nullable=true)
*/
private $createdBy;
please pay attention to all the #ORM\ everywhere.
Now, when using this with codeigniter2/Doctrine2.3.0 I have Mapping errors in my console.
But, when following some tuts, I ended up removing all of the ORM\ (and the corresponding use Doctrine\ORM\Mapping as ORM) and it worked.
This work :
<?php
namespace Entity;
/**
* Friend Model
*
* #Entity
* #Table(name="friend")
* #author Miles Yohann Merran <hello_miles#hotmail.com>
*/
class Friend
{
/**
* #Id
* #Column(type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="string", length=32, unique=true, nullable=false)
*/
protected $name;
/**
* #Column(type="text", nullable=false)
*/
protected $description;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $picture;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $genre;
/**
* #ManyToOne(targetEntity="User", inversedBy="friends")
* #JoinColumn(nullable=false)
*/
protected $user;
/**
* #var datetime $date
*
* #Column(name="date", type="datetime")
*/
protected $date;
When this doesn't work (pay attention at the ORM)
<?php
namespace Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Friend Model
*
* #Entity
* #Table(name="friend")
* #author Miles Yohann Merran <hello_miles#hotmail.com>
*/
class Friend
{
/**
* #Id
* #Column(type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="string", length=32, unique=true, nullable=false)
*/
protected $name;
/**
* #Column(type="text", nullable=false)
*/
protected $description;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $picture;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $genre;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="friends")
* #ORM\JoinColumn(nullable=false)
*/
protected $user;
/**
* #var datetime $date
*
* #ORM\Column(name="date", type="datetime")
*/
protected $date;
Why ? What is the difference ?
EDIT: To be exact, I tried 2 entites, with the same structure, one with #ORM\ before avery annotation sentence, and one without. The one with #ORM\ wasn't managed properly by Doctrine 2 when using the terminal commands and the one without works perfectly well. I wasn't able to find any documentation about that even if I clearly see both in the doc and the src that there is Doctrine Common, Doctrine ORM and Doctrine DBAL. Aren't they compatible between each other ? how to properly manage this difference ? especially when working with another framework than S (like CI2)
Thank you
Long story short, in symfony the doctrine annotation reader is an AnnotationReader, whereas in CI using the doctrine Setup::createAnnotationMetadataConfiguration helper, you have the SimpleAnnotationReader by default.
You should be able to have the same behavior as in symfony by passing false to the 5th argument $useSimpleAnnotationReader of Setup::createAnnotationMetadataConfiguration.