symfony2 doctrine decimal precision scale annotations are ignored - symfony

i've set up an attribute in my entity like this :
/**
* #var decimal
*
* #ORM\Column(name="latitude", type="decimal", precision=10, scale=7, nullable=true)
*/
private $latitude;
but when i generate the database schema with : doctrine:database:create; doctrine:schema:create
my field is set up to decimal (10,0) in the database (when i look up with phpmyadmin)
and so, when in insert data like 42.123456 with a form, this data is truncated to 42.
how can i resolve this?
Thanks.

Ok, finally get to resolve this.
Simply manually remove the cache (app/cache/..)
removing it by symfony command cache:clear wont revolve the problem

Related

Doctrine is trying to set default values even when none is defined

I am currently migrating from a legacy project to a Symfony4.
So I still need to keep the schema of the database.
I imported the database, and after fixing tons of issues I'm still unable to solve this one :
I have a join column where Doctrine is trying to set default value
$this->addSql('ALTER TABLE temperature_recording_system_sensor ALTER temperature_recording_system_site_uuid SET DEFAULT \'uuid_generate_v4()\'');
My column definition is actually like this :
/**
* #var TemperatureRecordingSystemSite
*
* #ORM\ManyToOne(targetEntity="TemperatureRecordingSystemSite")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="temperature_recording_system_site_uuid", referencedColumnName="temperature_recording_system_site_uuid", nullable=true, columnDefinition="DEFAULT NULL")
* })
*/
private $temperatureRecordingSystemSiteUuid;
How should I tell Doctrine to not set default values, as I can't use the option field on join column ?
I'm on Postgres 9.6.10 also.
Ia not trying to set a default value, plus it's on a JoinColumn, not a Column.

Doctrine2 what is the best way to update entities? ( Database => Doctrine )

Let's say I have all my entities set and I have my repositories linked in annotations like this:
/**
* User
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #ORM\Table(name="user")
*/
class User
{....}
now I go to my sql database and add a new column or any other change. I need to update doctrine model and at the moment I do it like this :
1 ) php bin/console doctrine:mapping:import App\\Entity annotation --path=src/Entity
2) php bin/console make:entity --regenerate App
these commands are purging my entities annotations and I get:
/**
* User
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User
{....}
3) I have to relink all my repositories manually in each entities (I have 12)
QUESTION:
Is there a way to update from database to entity while keeping all repository links at the top of my entities? How do you do it ?
I could not find anything in the doctrine manual; I was hoping for a doctrine:mapping:import setting ?
Instead of going from database to entity, go by another way: from entity to database
add needed property to the entity. like
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=true)
*/
protected $name;
run php bin/console doctrine:migrations:diff you will get migration with changes like $this->addSql('ALTER TABLE user ADD name VARCHAR(255) DEFAULT NULL');
run migration
EDIT
If you still want to go by your way, at least you could narrow down changes only to one entity by adding --filter="user" to both your commands

Doctrine ORM Custom Column Collation

I'm trying to set custom column collation as in Doctrine documentation:
http://doctrine-dbal.readthedocs.org/en/latest/reference/schema-representation.html and
http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html
using
#ORM\Column(name="body", type="string", length=140, options={"customSchemaOptions"={"collate"="utf8mb4_unicode_ci"}})
but when I update the schema it always goes back to utf8_unicode_ci (when I set it manually for example). Any ideas?
This has been added by now if you (or someone else) still need, see column annotation docs
Example: In annotations:
/**
* #var string
*
* #ORM\Column(type="string", length=64, nullable=false, options={"collation":"utf8_bin"})
*/
private $code;
In Yaml:
Your\Nice\Entity:
fields:
code:
type: string
length: 64
options:
collation: utf8_bin # Although the recommendation is the utf8mb4* set now.
This is supported by all common database drivers now.

Symfony2 & FOSRestBundle: Getting UUID packed in a BINARY(16) field from MySQL

I am facing a weird problem relating to UUIDs.
I have developed a REST API using Symfony2+FOSRestBundle+JMSSerializer. As I need to update some tables from two sources I thought of using UUID as primary key for one entity.
I did a doctrine:mapping:import to generate entities in my Symfony project. Everything correct. I ended up with the following entity (only exposing the key field and generated getter for simplicity):
<?php
namespace Stardigita\TgaAPIBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TgaBookings
*
* #ORM\Table(name="tga_bookings", indexes={[...]})
* #ORM\Entity
*/
class TgaBookings
{
/**
* #var string
*
* #ORM\Column(name="book_cd_booking_UUID", type="blob", length=16, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $bookCdBookingUuid;
/**
* Get bookCdBookingUuid
*
* #return string
*/
public function getBookCdBookingUuid()
{
return $this->bookCdBookingUuid;
}
...
No setter was generated. I can still do it myself and I will, as I will need to know the key beforehand.
The data for this field is correctly stored in the table as a BINARY(16). When I recover the data calling the REST GET method, I get this:
[
{
"book_cd_booking_uuid": "Resource id #1244",
"book_cd_booking": 8,
....
My question is: how can I get the actual data from the field?
I suppose something has to be done in the field getter, but I tried some solutions without any success.
Thanks.
UPDATE:
I've managed to get the actual data logged, modifying the getBookCdBookingUuid method this way:
/**
* Get bookCdBookingUuid
*
* #return string
*/
public function getBookCdBookingUuid()
{
return bin2hex($this->bookCdBookingUuid);
}
and changed the type to "guid" in the property annotation:
/**
* #var string
*
* #ORM\Column(name="book_cd_booking_UUID", type="guid", length=16, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $bookCdBookingUuid;
I have represented the hex UUID correctly in the log before returning the results in the controller:
[2014-11-03 19:52:07] app.ERROR: 1046684e5f6711e4a09f00089bce936a [] []
But still getting an exception relating UTF invalid characters:
request.CRITICAL: Uncaught PHP Exception RuntimeException: "Your data could not be encoded because it contains invalid UTF8 characters." at /var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php line 36 {"exception":"[object] (RuntimeException: Your data could not be encoded because it contains invalid UTF8 characters. at /var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php:36)"} []
Also I got no response from the service. A 500 error is returned.
Please, I need to solve this issue. Any ideas are welcome.
Thanks.
GeneratedValue
I notice you're using the annotation #ORM\GeneratedValue(strategy="IDENTITY") for the UUID property. IDENTITY means the database should/will use auto-increments, which shouldn't be done when using UUIDs. Please change it to #ORM\GeneratedValue(strategy="NONE") or remove it completely.
Conversion
The string form of a UUID (like 01234567-89ab-cdef-0123-456789abcdef) should be converted to binary when it's persisted in the database, and converted back when fetched from the database.
The easiest way to do this is to introduce a custom type. See here for an example.
Bugs
Doctrine (even master/2.5) has some issues with using UUIDs in associations. I'm attempting to fix these issues in PR #1178.
If you need UUIDs in associations and can't wait till it's fixed, then use regular integer ids and have the UUID is a separate column.

Doctrine Associations Mapping

I'm trying Doctrine Associations with Symfony2 for the first time and it's giving me headache.
I have an Admin interface that can, among other things, upload images. I want to know which administrator uploaded what image so i've putted a foreign key administrator to my images table. To gather data, a simple JOIN is necessary to collect the data but with Doctrine, I'm stuck, altough it seems simple.
So, I have an Administrator object that reflects the table. In that object, I have this statement...
#ORM\OneToMany(targetEntity="ImageBundleNamespace\ImageEntity", mappedBy="administrator")
It's simple. In my ImageEntity object (that reflects Images table) is a foreigh key column administrator.
In the ImageEntity object, I use this statement...
#ORM\ManyToOne(targetEntity="AdministratorNamespace\Administrator", inversedBy="imageEntity")
#ORM\JoinColumn(name="administrator", referencedColumnName="id")
There is a administrator field in ImageEntity and a imageEntity field in Administrator that the formentioned statements are mapping.
It doesn't work.
I've run the SchemaValidator on the EntityManger and it says the the administrator field on the ImageEntity object is not defined as an association. The second message says that the administrator field does not exist.
If it helps, this is my DQL for all of it...
'SELECT i.id,
i.imeSlike,
i.velicina,
i.ekstenzija,
i.paths,
a.username,
a.ime,
a.prezime FROM ImageBundle:ImageEntity i
JOIN a.administrator a'
Thank you in advance for all the help.
EDIT
I had a mistake in DQL. Corrected it.
EDIT
I forgot to add the source code.
Association part of the Administrator...
**
* #ORM\OneToMany(targetEntity="Icoo\Administracija\GalerijaBundle\Entity\ImageEntity", mappedBy="administrator")
*/
protected $imageEntity;
public function __construct() {
$this->imageEntity = new ArrayCollection();
}
Association part of the ImageEntity
/**
* #ORM\Column(type="smallint")
*
* #ORM\ManyToOne(targetEntity="Icoo\LoginBundle\Entity\Administrator", inversedBy="imageEntity")
* #ORM\JoinColumn(name="administrator", referencedColumnName="id")
*
*/
protected $administrator;
In the administrator class, you have:
/**
* #ORM\Column(type="smallint")
*
* #ORM\ManyToOne(targetEntity="Icoo\LoginBundle\Entity\Administrator", inversedBy="imageEntity")
* #ORM\JoinColumn(name="administrator", referencedColumnName="id")
*
*/
you need to remove the #ORM\Column(type="smallint")
This must be all. Let me know.
You can separate field mapping from association mapping:
/**
* #ORM\Column(name="administrator", type="smallint", nullable=false, options={"unsigned"=true})
*/
protected $administratorId;
/**
* #ORM\ManyToOne(targetEntity="Icoo\LoginBundle\Entity\Administrator", inversedBy="imageEntity")
* #ORM\JoinColumn(name="administrator", referencedColumnName="id")
**/
protected $administrator;
If you go further you can put exception into $administratorId getter/setter to avoid usage of it.
As i have tested, doctrine ignores value into $administratorId property when you persist/flush your entity (For confirmation you can look at prepareUpdateData() in Doctrine\ORM\Persisters\BasicEntityPersister)
EDIT
I think, my previous variant is possible but wrong. Because, doctrine gets field mapping from definitions in referencedColumn, you can add some more definitions using
* #ORM\JoinColumn(name="administrator", referencedColumnName="id", unique, nullable, onDelete, columnDefinition, fieldName)
This means that your image_entity.administrator field in db will be the same as your administrator.id field in db (except of additional definitions)

Resources