We're porting over an application to Symfony2 and are currently stuck using doctrine ORM. We have a bunch of bad foreign keys in the database and it's getting increasingly more difficult to do the relationship mappings with out running into an "Entity not found" exception. It's on the roadmap to clean up the database but it's not something we can tackle right now unfortunately. Is there any way I can make it just return null if it fails to look up the proper entity?
If I have the following relationship mapping:
User:
type: entity
table: user
id:
userID:
type: integer
generator:
strategy: NONE
fields:
contactName:
type: string
length: 255
nullable: false
contactPhone:
type: string
length: 255
nullable: false
companyName:
type: string
length: 255
nullable: false
username:
type: string
length: 255
nullable: false
password:
type: string
length: 255
nullable: false
email:
type: string
length: 255
nullable: false
manyToOne:
address:
targetEntity: Address
joinColumn:
name: addressID
referencedColumnName: addressID
nullable: true
default: null
-----------------------------------------------------
Address:
type: entity
table: address
id:
addressID:
type: integer
generator:
strategy: AUTO
fields:
street:
type: string
length: 255
nullable: false
street2:
type: string
length: 255
nullable: false
city:
type: string
length: 255
nullable: false
state:
type: string
length: 32
nullable: false
zip:
type: string
length: 10
nullable: false
country:
type: string
length: 40
nullable: false
It seems that if there is a bad value for addressID in the user table i'll get an "Entity was not found." exception when sending it through the serializer.
I just encountered this same issue and found this question when searching for a solution... which I didn't find. Here's what I did (using annotation):
Make the relationship lazy:
/**
* @var Resource
*
* @ORM\JoinColumn(name="ResourceID", referencedColumnName="ResourceID")
* @ORM\OneToOne(targetEntity="Resource", fetch="LAZY")
*/
private $resource;
private $_resource_is_valid = null;
Modify the getter and always use it -- even internally in the class:
/**
* Returns the associated resource, accounting for bad references.
* @return Resource|null
*/
public function getResource()
{
if (is_null($this->_resource_is_valid))
{
try
{
// We need to call a method that triggers a lazy load
if ($this->resource && $this->resource->getID())
{
$this->_resource_is_valid = true;
}
}
catch (\Doctrine\ORM\EntityNotFoundException $enf)
{
$this->_resource_is_valid = false;
// consider creating a new resource object.
}
}
if ($this->_resource_is_valid)
{
return $this->resource;
}
return null;
}
This approach allows Doctrine to partially hydrate entities, and lets you trap the bad relationship in an area where you have more control.
Ah, this is the PITA that we see quite often too. If you've got lazy loading disabled then Doctrine could be loading & hydrating all linked entities at the time. But I'm guessing its turned on and its dying when you try and render a template / form in Symfony.
With Lazy Loading on, you won't get the error when you load the entity, you will however get the error if you then try and access a property of the related entity (which will cause Doctrine to load it) or render the entity in a symfony form and a field on the form relates to a property of the foreign table.
Unfortunately there is no easy way to stop or catch this. My advice would be to manually check the data for bad foreign keys and clean up the data, Doctrine's lazy loading is particularly unforgiving of bad data and Symfony just makes this worse by blowing up with an Error 500 if it comes across a duff link.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With