Symfony + Doctrine 2.2 DateTime column error - php

I'm having a hard time sorting this issue out. I'm getting the following error while trying to persist an entity (see source below):
Fatal error: Call to a member function format() on a non-object
in *****\vendor\doctrine-dbal\lib\Doctrine\DBAL\Types\DateTimeTzType.php
on line 64
Here's a snippet of the entity's code:
namespace ****\Bundle\****Bundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* ****\Bundle\****Bundle\Entity\MyEntity
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="****\Bundle\****Bundle\Entity\****Repository")
* #ORM\HasLifecycleCallbacks()
*/
class MyEntity
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime $created_at
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var \DateTime $updated_at
*
* #ORM\Column(name="updated_at", type="datetime", nullable="true")
*/
private $updated_at;
/**
* Set created_at
*
* #param datetime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
}
/**
* Get created_at
*
* #return datetime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set updated_at
*
* #param datetime $updatedAt
*/
public function setUpdatedAt($updatedAt)
{
$this->updated_at = $updatedAt;
}
/**
* Get updated_at
*
* #return datetime
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
* #ORM\PrePersist()
*/
public function executePrePersist()
{
$this->created_at = new \DateTime();
}
/**
* #ORM\PreUpdate()
*/
public function executePreUpdate()
{
$this->updated_at = new \DateTime();
}
}
Before posting here, I've added:
print_r(get_class($value))
to DateTimeTzType.php at the offending place to know which kind of data it received, and I got the following error:
Warning: get_class() expects parameter 1 to be object, string given
So it seems that it is receiving a string instead of a DateTime object, and then fails because string doesn't have a format() method.
I'm using Symfony 2.0.9. Am I missing something?

Seems like your setCreatedAt() and getCreatedAt() do not specify they require DateTime as a type, which Doctrine expects.
You can either make sure you create a DateTime object when calling those functions or modify the methods to check if a string was provided as the input and create the object when needed. Just sending the string representation of the date as the first argument to the DateTime constructor usually works.

It was my error. I had another field with DateTime type elsewhere in my entitiy and I was passing a string to it before persisting. I was convinced it was the createdAt field. Thanks xdebug and sorry for the post.

Related

Doctrine ArrayCollection Call to a member function setValue() on null

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

Symfony2 Datetime TransformationFailed Exception

i'm stuck in error when try to generate CRUD in symfony2 I always get the following exception:
"Unable to transform value for property path "xxx": Expected a \DateTime or \DateTimeInterface."
it always happened with the any datetime field here is excerpt of my entity field:
/**
* #var \DateTime
*
* #ORM\Column(name="date_added", type="datetime", nullable=false)
*/
private $dateAdded = '0000-00-00 00:00:00';
/**
* Set dateAdded
*
* #param \DateTime $dateAdded
*
* #return User
*/
public function setDateAdded()
{
$this->dateAdded = new \DateTime();
return $this;
}
/**
* Get dateAdded
*
* #return \DateTime
*/
public function getDateAdded()
{
return $this->dateAdded;
}
-Also i tried to use easyadmin bundle which generate backend from entities using symfony2 CRUD on the fly but also get the same error so is there something wrong with my entity ?
Maybe removing the annotation #param \DateTime $dateAdded as your function setDateAdded() has no parameter ?
The $dateAdded field cannot contain a string. It needs to have a DateTime object, because that's whats expected. In other words you need to have a constructor which sets the date:
/**
* #var \DateTime
*
* #ORM\Column(name="date_added", type="datetime", nullable=false)
*/
private $dateAdded;
public function __construct() {
$this->dateAdded = new \DateTime();
}
Also, you need to accept a parameter on your setDate method:
public function setDate($date) {
$this->dateAdded = $date;
}
As a side note, keep in mind you will need to use a date filter if you'll be displaying the date in a twig template:
{{ entity.dateAdded|date('d.m.Y') }}

Doctrine get full entity after a partial query

I am working on a system that is build using Zend Framework 2 and Doctrine 2.
In this system I am working on the contracts part where I want a list with some data (a partial query) from all contracts and I need to fill in a form with all data (entity find) from a specific contract.
However, since the contract to be filled in the form is also a result of the partial query, the properties that had not been loaded in the PARTIAL query will not be loaded for the queried entity either.
I have simplified the data to show only the current issue, the real entity has more fields:
Entity:
use Doctrine\ORM\Mapping as ORM;
/**
* ContractSub
*
* #ORM\Table(name="contract_sub", indexes={#ORM\Index(name="contract_id", columns={"contract_id"}), #ORM\Index(name="list_pension_start", columns={"list_pension_start_id"}), #ORM\Index(name="list_lease_car_category", columns={"list_lease_car_category_id"}), #ORM\Index(name="created_by_id", columns={"created_by_id"})})
* #ORM\Entity(repositoryClass="Application\Repository\ContractSubRepository")
* #ORM\HasLifecycleCallbacks
*/
class ContractSub
{
/**
*
* #var integer #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
*
* #var \DateTime #ORM\Column(name="start_date", type="date", nullable=false)
*/
private $startDate;
/**
*
* #var \DateTime #ORM\Column(name="end_date", type="date", nullable=true)
*/
private $endDate;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set startDate
*
* #param \DateTime $startDate
*
* #return ContractSub
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this;
}
/**
* Get startDate
*
* #return \DateTime
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate
*
* #param \DateTime $endDate
*
* #return ContractSub
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this;
}
/**
* Get endDate
*
* #return \DateTime
*/
public function getEndDate()
{
return $this->endDate;
}
}
Repository:
use Doctrine\ORM\EntityRepository;
class ContractSubRepository extends EntityRepository
{
public function getPartialStuffForTest()
{
$oQuery = $this->_em->createQuery('SELECT PARTIAL ContractSub.{id, startDate}
FROM Application\Entity\ContractSub ContractSub');
return $oQuery->getResult();
}
}
Controller:
use Zend\Mvc\Controller\AbstractActionController;
class ContractController extends AbstractActionController
{
public function testAction()
{
$oEntityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$aContracts = $oEntityManager->getRepository('Application\Entity\ContractSub')->getPartialStuffForTest();
$oContractSub = $oEntityManager->getRepository('Application\Entity\ContractSub')->find(38);
var_dump($oContractSub->getStartDate());
var_dump($oContractSub->getEndDate());
die();
}
}
This outputs:
object(DateTime)[479]
public 'date' => string '2015-06-01 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Amsterdam' (length=16)
null
Indicating that the endDate is not loaded, even though I do a find to retrieve the complete entity.
When I comment the line that executes the getPartialStuffForTest(), I do get the endDate as well.
So I was wondering if there is any way to force Doctrine to retrieve the full entity after it already has a cached version of the partial entity?
To fully load a partial you have to use $entityManager->refresh($object).
Your answer is in the first paragraph in the Doctrine2 documentation chapter 18. Partial objects.
Use of partial objects is tricky. Fields that are not retrieved from the database will not be updated by the UnitOfWork even if they get changed in your objects. You can only promote a partial object to a fully-loaded object by calling EntityManager#refresh() or a DQL query with the refresh flag.

Doctrine annotations try to autoload wrong annotation

I try to use Symfony 2.6/Doctrine 2 on Ubuntu 14.04 with php5.5.9/mysql5.5. But i get very strange error and couldn't find any solution.
I create very simple entity with doctrine:generate:entity command. Everything is just fine. But when I try to create table with doctrine:schema:update command I get an imposible to fix error :)
[Doctrine\Common\Annotations\AnnotationException]
[Semantical Error] The annotation "#Doctrine\ORM\Mapping\I" in property AppBundle\Entity\Language::$id does not exist, or could not be auto-loaded.
Well, actually it's right. There is nothing such #Doctrine\ORM\Mapping\I.
It's all about #ORM\Id. When I change #ORM\Id, the error also changes. I change it to #ORM\Hello, the error changes as #Doctrine\ORM\Mapping\Hello. But when I change it to #ORM\Isthisreal, the error stand still as #Doctrine\ORM\Mapping\I.
I thing there is some parsing error about case sensitiveness. But couldn't find any sollution. I tried lots of things but nothing changes. Here is my simple entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Language
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\LanguageRepository")
*/
class Language
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var boolean
*
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* #var string
*
* #ORM\Column(name="iso", type="string", length=2)
*/
private $iso;
/**
* Get id
*
* #return integer
*/
public function getid()
{
return $this->id;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return Language
*/
public function setisActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getisActive()
{
return $this->isActive;
}
/**
* Set iso
*
* #param string $iso
* #return Language
*/
public function setiso($iso)
{
$this->iso = $iso;
return $this;
}
/**
* Get iso
*
* #return string
*/
public function getiso()
{
return $this->iso;
}
}
Try run this before doctrine:schema:update
export LC_ALL=C

Symfony-2.3 entity repository error

I'm usual working with symfony from the 2.1 or 2.2 versions.
Today i started a new project on the 2.3 and i'm encountering problems to create my custom entity repository.
My entity is:
<?php
namespace Acme\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* AnnualProduction
*
* #ORM\Table(name="Annual_Production")
* #ORM\Entity(repositoryClass="Acme\MyBundle\Entity\AnnualproductionRepository")
*/
class AnnualProduction
{
/**
* #var string
*
* #ORM\Column(name="device_address", type="string", length=45, nullable=true)
*/
private $deviceAddress;
/**
* #var integer
*
* #ORM\Column(name="mese_1", type="integer", nullable=true)
*/
private $mese1;
/**
* #var integer
*
* #ORM\Column(name="mese_2", type="integer", nullable=true)
*/
SOME MISSING VAR SET AND GET
/**
* #var string
*
* #ORM\Column(name="sens_id", type="string", length=45)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $sensId;
/**
* #var \DateTime
*
* #ORM\Column(name="AAAA", type="date")
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $aaaa;
/**
* Set deviceAddress
*
* #param string $deviceAddress
* #return AnnualProduction
*/
public function setDeviceAddress($deviceAddress)
{
$this->deviceAddress = $deviceAddress;
return $this;
}
/**
* Get deviceAddress
*
* #return string
*/
public function getDeviceAddress()
{
return $this->deviceAddress;
}
/**
* Set mese1
*
* #param integer $mese1
* #return AnnualProduction
*/
public function setMese1($mese1)
{
$this->mese1 = $mese1;
return $this;
}
/**
* Get mese1
*
* #return integer
*/
public function getMese1()
{
return $this->mese1;
}
/**
* Set sensId
*
* #param string $sensId
* #return AnnualProduction
*/
public function setSensId($sensId)
{
$this->sensId = $sensId;
return $this;
}
/**
* Get sensId
*
* #return string
*/
public function getSensId()
{
return $this->sensId;
}
/**
* Set aaaa
*
* #param \DateTime $aaaa
* #return AnnualProduction
*/
public function setAaaa($aaaa)
{
$this->aaaa = $aaaa;
return $this;
}
/**
* Get aaaa
*
* #return \DateTime
*/
public function getAaaa()
{
return $this->aaaa;
}
}
I dont write all variable and get and sets functions.
I've created a repository file: Acme\MyBundle\Entity\AnnualproductionRepository.php
The code for the repository file is the following:
<?php
namespace Acme\MyBundle\Entity;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Acme\MyBundle\Entity\AnnualProduction;
class AnnualproductionRepository extends EntityRepository
{
public function findByYearMonthDay($anno, $mese, $giorno, $sensId)
{
$query = $this->getEntityManager()
->createQuery(" SOME QUERY HERE")->setParameters(array(SOME PARAMETERS HERE));
return $query->getSingleResult();
}
}
I call the repository in one of my controller, with the following code:
<?php
namespace Acme\MyBundle\Controller;
use Acme\MyBundle\Entity\AnnualProduction;
use Acme\MyBundle\Entity;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Constraints\Date;
class DataController extends Controller{
public function indexUserAction(){
*
*
*
*
*
$DailyProduction=$DailyProduction+$em->getRepository('AcmeMyBundle:AnnualProduction')->findByYearMonthDay($year, $month, $day, $productionSensor);
*
*
*
*
}
}
But i get this error like the repository doesnt exist and the controller get the function name like a default findBy* on one of the Entity attributes.
ERROR:
*> Entity 'Acme\MyBundle\Entity\AnnualProduction' has no field
'yearMonthDay'. You can therefore not call 'findByYearMonthDay' on the
entities' repository***
Have you some advise to solve this problem? the code seems to be identical to the one i usualy add to include custom entity repository in symfony 2.2 but for some reason it refuse to work.
Tx for your time and Help.
Problem Solved, the fact was that the entity.orm.xml files, stored in /src/acme/myBundle/config/doctrine, have an hight priority over the entity files, so every modification to the entity that i was doing wasent readed.
SOLUTION: Delete all the entity.orm.xml files after done the annotation ed the generation of the entity via terminal php command.
The namespace for your repository is wrong. You should have Acme\MyBundle\Entity\Repository for a namespace instead. The path to your file ought to then be Acme/MyBundle/Entity/Repository/AnnualProduction.
You should also let doctrine generate all your entities for you via
php app/console doctrine:generate:entities Acme
You will then see a folder called Repositories in your Entities folder and thats where all the entities need to be stored.

Categories