Doctrine OneToMany Relation based on entityUid field - php

i'me working on a project with alot of the entities have string uid LIKE ENTITY.XXXX.
I'm seaching a way to relate some entities using doctrine annotations.
In particular the entity Media that contains all the links to the media files, to other entities becouse the relations between Media and the other entities like Document, Building etc is based on a field entityUid inside the Media entity, so the field entityUid is promiscuous becouse can contain the uid form different other entities.
I realize that cannot do a reverse mapping becouse i cant populate correctoy the reversed entity becouse is promiscuous, what i'm trying to do is a direct relation between for example Document 1:n Media based on Document.uid 1:n Media.entityUid and Bulding 1:n Media based on Document.uid 1:n Media.entityUid.
I write the entities:
class Media(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
* #var string
* #ORM\Column(name="entityUid", type="string", nullable=false)
*/
private $entityUid;
/**
* #var string
*
* #ORM\Column(name="link", type="string", nullable=true)
*/
private $link;
... other stuff.
}
class Document(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
*#var Media[]
*
*/
private $medias;
/**
* #var string
* #ORM\Column(name="uid", type="string", nullable=false)
*/
protected $uid;
... other stuff
}
class Building(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
*#var Media[]
*
*/
private $medias;
/**
* #var string
* #ORM\Column(name="uid", type="string", nullable=false)
*/
protected $uid;
... other stuff
}
The problem is on the definition on the relation OneToMany, based not form the id fiels but uid fileds.
I was not able to find a correct annotation to create an unidirection OneToMany relation without creating a support table like a ManyToMany document_media , building_media, that would make useless the entities uids.
Tx for your time.

Related

Doctrine Refactor entities

Hello i am using Doctrine ORM, i have major problem. Overall i have 10 tables, each table has it's own address fields(street, city, state, zip). So basically i am trying to refactor db structure, and created one new address table with those fields, old tables will hold address_id as a reference, and i will remove address fields from each table, and migrate data.
Since it's very big project with large code base trying to determine whats the best approach to do this refactoring regarding entities.
Things to concern
find() method
findBy() method
persist
Query Builder
Here it's my userCreditCard entity, it has address object in it, and that object should be replaced with "address_id".
class UserCreditCard extends LoggableEntity implements UserCreditCardInterface
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var int|null
*
* #ORM\Column(name="user_id", type="integer", nullable=true)
*/
protected $userId;
/**
* #var string
*
* #ORM\Column(name="cc_number", type="string", length=255, nullable=false)
*/
protected $ccNumber;
/**
* #var string
*
* #ORM\Column(name="cc_name", type="string", length=255, nullable=false)
*/
protected $ccName = '';
/**
* #var \DateTime
*
* #ORM\Column(name="cc_date", type="date", nullable=false)
*/
protected $ccDate;
/**
* #var bool
*
* #ORM\Column(name="bill_addr_type", type="boolean", nullable=false)
*/
protected $billAddrType = false;
/**
* #var UserBillingAddress
* #ORM\Embedded(class = "\Cae\User\Dal\Entity\Embeddable\UserBillingAddress", columnPrefix=false)
*/
protected $address;
Here is address object.
/** #ORM\Embeddable */
class UserBillingAddress extends AbstractAddressEmbeddable
{
/**
* #var string
*
* #ORM\Column(name="bill_street_address", type="string", length=255, nullable=false)
*/
protected $address = '';
/**
* #var string
*
* #ORM\Column(name="bill_street_address2", type="string", length=255, nullable=false)
*/
protected $address2 = '';
/**
* #var string
*
* #ORM\Column(name="bill_city", type="string", length=255, nullable=false)
*/
protected $city = '';
My question would be since it's very large project is it possible to some how override with entity listeners or with magic setter so for example when someone do
$this->userCreditCardRepository->find($id);
pull address data from new Address table (i can't do joins since address table lives in another module, so i have to use public services).
Maybe to override find, findBy and other methods in AbstractRepository, but i am not sure what the best approach? Any idea is appreciated.

Mysql relationship between tables

I have a question to now what is the best solution to make relations between tables:
I have :
client table with id name sector_id delegation_id
sector table with id name
delegation table with id name sector_id
My question is that is it a good practice to have both foreign keys in the client table or just the key of delegation_id is sufficient for indexing and searching in the client table (of course with join tables)
to explain more
each delegation belongs to a sector.
each sector belongs to a zone
and each Client belongs to a delegation that belongs to a sector that is grouped in a geographical area
this is my Entity files :
Class client
class Client {
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="firstName", type="string", length=255)
*/
private $firstName;
/**
* #var string
*
* #ORM\Column(name="lastName", type="string", length=255)
*/
private $lastName;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="sector", type="string", length=255)
*/
private $sector;
/**
* #var int
*
* #ORM\Column(name="delegation", type="integer")
*/
private $delegation;
}
Class sector
class Sector {
/**
* #ORM\Id
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Delegation" ,mappedBy="sector")
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
*/
private $name;
/**
* #Assert\NotBlank()
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Zone", inversedBy="id")
* #ORM\JoinColumn(nullable=false)
*/
private $zone;
}
class Delegation
class Delegation {
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Sector", inversedBy="id" )
* #ORM\JoinColumn(nullable=false)
*/
private $sector;
}
Based on your updated question -
If each Client belongs to a Delegation, the Client entity should have a delegation_id foreign key.
If each Delegation belongs to a Sector, the Delegation entity should have a sector_id foreign key.
And if each Sector belongs to a Zone, the Sector entity should have a zone_id foreign key.
You would therefore remove your sector_id foreign key from your Client entity, and use the relationship through the Delegation entity to find all Client entities within a given Sector, if this were ever required.

Symfony 2.3 Join tables using composite keys

have a element class with composite keys.
When I run php app/console doctrine:schema:validate
I get the following error
The join columns of the association 'parentElement' have to match to
ALL identifier columns of the target entity
'AgRecord\AppBundle\Entity\Element', however 'id, parent_uuid' are
missing.
What am I missing or how do I correctly describe the relationship?
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* Elements
*
* #ORM\Table(name="elements",uniqueConstraints={#ORM\UniqueConstraint(name="search_idx", columns={"uuid", "id", "parent_uuid"})})
* #ORM\Entity
*/
class Element
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", columnDefinition="INT AUTO_INCREMENT UNIQUE")
* #ORM\Id
*/
private $id;
/**
* #var guid
* #ORM\Id
* #ORM\Column(name="uuid", type="string", unique=true, nullable=false)
*/
private $uuid;
/**
* #var guid
* #ORM\Id
* #ORM\Column(name="parent_uuid", type="string")
*/
private $parentUUID;
/**
* #ORM\ManyToOne(targetEntity="Element", inversedBy="childElements")
* #ORM\JoinColumn(name="uuid", referencedColumnName="parent_uuid")
*/
private $parentElement;
/**
* #ORM\Id
* #ORM\OneToMany(targetEntity="Element", mappedBy="parentElement")
* #ORM\JoinColumn(name="uuid", referencedColumnName="element_uuid")
*/
private $childElements;
}
I was stupid I had all the mappings mixed up...
I solved my issue kind of.
First I decided to just remove id and have uuid, which meant i didnt need a composite key.
Then needed to remove stupidly placed #Id off of all non primary fields
Then removed the $parentUUID.
I was doing it the wrong way and didn't understand the mapping, and using an extra reference when it wasn't needed.
Then removed the joined annotation from the child elements and made sure to have the inversedby correctly set on the parent.
The name on the parent join annotation needs to be the name of the class member associated.
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* Elements
*
* #ORM\Table(name="elements")
* #ORM\Entity
*/
class Element
{
private $id;
/**
* #var guid
* #ORM\Id
* #ORM\Column(name="uuid", type="string", unique=true, nullable=false)
*/
private $uuid;
/**
* #ORM\ManyToOne(targetEntity="Element", inversedBy="childElements")
* #ORM\JoinColumn(name="parentElement", referencedColumnName="uuid")
*/
private $parentElement;
/**
* #ORM\OneToMany(targetEntity="Element", mappedBy="parentElement")
*/
private $childElements;
}

unique_base option of sluggable exention doesn't accept a foreign key

I have entity Store and entity Category and each Store can add his own categories.
I'd like to generate an unique Slug for each Category based on foreign key store_id. I tried using "unique_base" option but it doesn't work.
Why the "unique_base" option of Sluggable extension does not accept a foreign key ?
class Category
{
/**
* #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;
/**
* #Gedmo\slug(fields={"name"}, unique_base="store")
* #ORM\Column(name="slug",length=255, unique=false)
*/
private $slug ;
/**
* #ORM\ManyToOne(targetEntity="Project\StoreBundle\Entity\Store", inversedBy="categories", cascade={"persist"})
* #ORM\JoinColumn(nullable=true)
*/
private $store ;
//.................
}
Looking at the Sluggable Docs you need to use RelativeSlugHandler: to handle foreign-keys

doctrine property mapping

I just started working with symfony and doctrine. I have a simple entity which has one property is not tied with the database. This property should contain the contents of the xml file (I wanna make xml file, when doctrine add rows to the database).
/**
* Layouts
*
* #ORM\Table(name="layouts")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class Layouts
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="layouts_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* ???????
*/
private $template_body;
...
}
How to describe $template_body property? Without leaving the property description, I ran into a problem - the doctrine does not cause preUpdate method when I edit this property in the form.
You can do that my simply flagging a PreUpdate method in your class, which in turn begins working on your $template_body variable.
Please change
* #ORM\HasLifecycleCallbacks()
to
* #ORM\HasLifecycleCallbacks
and create a function like so..
/**
* #PreUpdate
*/
public function myUpdateFunction()
{
// Do stuff
}

Categories