Reputation: 804
another question. I have a abstract BaseLog Entity which keeps the association to my user. In addition I have 2 Entities (FooLog & BarLog) which extend BaseLog. In addition I have my User Entity which are suppose to hold two associations to Log. One for FooLog and one for BarLog. Here is my issue. I get error messages because I don't know how to overwrite BaseLog's inversedBy field in extending Entity. Could you please help me.
Because I think my explanation is not really good, here the Set up of my entities.
BaseLog
/** @ORM\MappedSuperclass */
abstract class BaseLog {
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="logs")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
* })
*/
private $user;
}
FooLog
/** @ORM\Entity */
class FooLog extends BaseLog {
// Some additional fields
}
BarLog
/** @ORM\Entity */
class BarLog extends BaseLog {
// Some additional fields
}
User
/** @ORM\Entity */
class User {
/**
* @ORM\OneToMany(targetEntity="FooLog", mappedBy="user", cascade={"persist"})
*/
private $fooLogs;
/**
* @ORM\OneToMany(targetEntity="BarLog", mappedBy="user", cascade={"persist"})
*/
private $barLogs;
}
How do I have to overwrite BaseLog's inversedBy in FooLog & BarLog.
I get several Mapping error on this set up: BaseLog
Please help me to get my mapping sorted.
Upvotes: 8
Views: 6035
Reputation: 2387
The correct way to do this (since Doctrine 2.3) is using AssociationOverrides
.
Remove inversedBy="logs"
from BaseLog
class - since a mapped super class doesn't represent a real entity anyway - and then override it in subclasses. Here's how that should look:
BaseLog
/** @ORM\MappedSuperclass */
abstract class BaseLog {
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
* })
*/
private $user;
}
FooLog
/**
* @ORM\Entity */
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride(name="user", inversedBy="fooLogs")
* })
*/
class FooLog extends BaseLog {
// Some additional fields
}
BarLog
/**
* @ORM\Entity */
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride(name="user", inversedBy="barLogs")
* })
*/
class BarLog extends BaseLog {
// Some additional fields
}
name=
in @ORM\AssociationOverride
represents the field you want to override from the mapped super class.
Upvotes: 2
Reputation: 3393
IIRC there was not good way to override mappings in older versions of Doctrine. In Doctrine >= 2.2 there is something called association override so maybe you can use it.
BTW Why do you not want move associations from base to concrete classes and define valid inversedBy then ?
Upvotes: 1
Reputation: 154
I had similar issue with single inheritance. I resolved this by defining same association in both entity classes (parent and inherited) but with different name. In your case you can try this:
/** @ORM\Entity */
class FooLog extends BaseLog {
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="foologs")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
* })
*/
private $user;
}
and in class BarLog:
/** @ORM\Entity */
class BarLog extends BaseLog {
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="barlogs")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
* })
*/
private $bar_user;
}
Notice different name ($bar_user). You also have to define foologs and barlogs properties in user entity. This removes doctrine validation errors.
Upvotes: 4
Reputation: 5036
I have struggled with the same issue using Single Table Inheritance. As far as I can tell there isn't a solution to it. Even though inversedBy
is considered compulsory, it seems you can get away with ignoring it. However, as the Doctrine docs suggest the performance deteriorates rapidly.
@AssociationOverride
doesn't help, because you can't modify association definitions, only database column properties.
I've tried a number of options, none of which are satisfactory.
Update: I still haven't been able to find any solution to these sorts of errors when running app/console doctrine:schema:validate
.
[Mapping] FAIL - The entity-class 'Acme\AcmeBundle\Entity\CourseLocation' mapping is invalid:
* The field Acme\AcmeBundle\Entity\CourseLocation#facilitators is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Acme\AcmeBundle\Entity\CourseFacilitatorResponsibility#courseLocation does not contain the required 'inversedBy' attribute.
In this instance CourseFacilitatorResponsibility
is a sub-class (with single table inheritance) of CourseResponsibility
. CourseLocation
refers to multiple CourseResponsibility
entities. I think uni-directional associations is the only way around it.
Upvotes: 3