I am quite confused setting up cascade deletes in Doctrine 2. Here's what my setup looks like
I want to setup cascading so that I can do something like $list->getStages()->clear()
I tried in Stage class
/**
* #OneToMany(targetEntity="TaskProgress", mappedBy="stage", cascade={"remove"})
*/
protected $taskStages;
But that did nothing, I even tried putting the same thing in other classes like List, TaskProgress or Task but nothing seem to work, I may have done it wrong tho ..
Cascade remove is not used when calling "clear". Its called when you pass the Stage class to EntityManager#remove(), then all TaskProgress entities are also deleted.
Related
How can I create and import a move filter on construction heuristics?
Solution
optaplanner at configuration may show some errors when you try to add and on configuration. It is possible to need one more tag or something else, but for something was missing or was doing it totaly wrong.. I finaly managed to add my filter by creating customfilter class whis implements SelectionFilter and add to the annotation of the entity class. Find in the documentation the SelectionFilter class.##
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
<changeMoveSelector>
<filterClass>...</filterClass>
</changeMoveSelector>
</constructionHeuristic>
Without scrutinizing why I want this (it may sound like a bad approach, but I have good reason) I want to know if there is a way in the standard-framework-edition 3.1+ to create a relational association to an entity that may not exist...
Firstly I do realize this determines the schema and that's fine. So if an entity does not exist, it doesn't create a foreign key and the field is always null, or if the target entity does exist, it creates the foreign key and the field works like a normal association...
Secondly, this only changes project to project, and may change down the line as an update to which I realize a manual schema update could be necessary.
Preferably without 3rd party bundle dependencies... hoping for the standard framework to do this,
Anybody?
Thanks in advance
Edit
I am using annotations in my entities with doctrine ORM
Furthermore
The simplest version of why I am doing this is because certain bundles are optional project-to-project, and bundle A may make use of entities in bundle B only if it is present. I have considered using services and if container->has then container->get, or the XML on-invalid="null" approach, but that doesn't address property persistence. I was happy with storing a non-mapped value as a custom relational field, which is fine, just lengthier and wondered if perhaps there was a way Doctrine could ignore a missing targetEntity...
Hm, perhaps I misunderstand your question, but this sounds like a normal 'nullable' association to me?
Create your assocation via annotation:
/**
*
* #var Child
* #ORM\ManyToOne(targetEntity="Child")
*/
private $child;
and use
setChild(Child $child = null)
{
$this->child = $child;
}
as a Setter to allow nullable values.
And your getter might look like:
getChild()
{
return $this->child;
}
In case there isn't any child it will return null.
I will keep the other answer as it responds to the question for a 'nullable association target' live data.
This is the answer for a 'nullable association target' meta data which is a different thing.
OP asks to provide a targetEntity in the metadata which cannot exist in his case, e.g. is not there in a different bundle (or whatever OP's mysterious reason might be).
In that case I recommend to build upon Doctrine's TargetEntityListener which is able to resolve the targetEntity during runtime and targetEntity can be set to an Abstract Class or an Interface:
/**
* #ORM\ManyToOne(targetEntity="Acme\InvoiceBundle\Model\InvoiceSubjectInterface")
* #var InvoiceSubjectInterface
*/
protected $subject;
InvoiceSubjectInterface will then be replaced during runtime by a specific class provided by config e.g.:
# app/config/config.yml
doctrine:
# ...
orm:
# ...
resolve_target_entities:
Acme\InvoiceBundle\Model\InvoiceSubjectInterface: AppBundle\Entity\Customer
So this should be eiter an extendable behaviour for providing no class or implementing an own solution.
So I'm working on some unit tests and relational fixtures.
I'm creating a model dynamically like:
$model = CActiveRecord::model('Post');
$post = $model->findByPk(1);
But after that I cannot for some reason get $post->id. I traced the problem to CActiveRecord class:
public function __get($name)
{
if(isset($this->_attributes[$name]))
return $this->_attributes[$name];
...
Where $name = "id". It says that $this->_attributes[$name] does not exist! As a matter of fact _attributes is empty.
My Post class does not define id (or any other properties) as a public property and I don't want to do so either. I just let the AR map it to table columns for me.
What am I missing?
Edit 1
My fixtures are regular Yii fixtures - nothing really special about them.
What differs is the way I load them really. I extended the CDbFixtureManager to be able to specify the order in which they should be loaded by overloading load() method. Only thing of interest that actually fails is that in the fixtures that have foreign keys I use the following:
'comment1' => array('post_id' => $this->getRecord('Post', 'post1')->id);
That's where it fails. getRecord returns the actual Post record (since I know the Post fixture has already been successfully loaded and exists in DB), but on the ->id part I get an exception about that attribute not existing.
If I go into Post model and add public $id; to it, then everything works! But I'm not sure if it's good practice to go about declaring all properties public like that.
If you look at this page carefully:
http://www.yiiframework.com/doc/guide/1.1/en/test.unit
you'll see that they use an array form for retrieving fixtures:
$this->posts['sample1']['id']
There is an alias defined in their fixture array for each record and fixture items aren't loaded as models really ...
Does that help? If not, it would be helpful to see your fixture file :-)
I think I found the root cause of this issue for me. While my FixtureManager was using the testdb DBConnection, the models still used the regular one.
For whatever reason, my debugger was giving me misleading errors like the one described in my original post.
Once I was able to set the DBConnection of all Models in the unit test the puzzle snapped into place and everything is now working smoothly!
HI, I want somehow to figure out which field was updated in the controller, I didn't found anything that might sound like what I'm trying to achieve in API doc for UnitOfWork.
For example, I want to add on #PreUpdate code similar to this
/** #PreUpdate */
function updateAllIsDefaultFields(){
//only if $this->isDefault propery for this entity is changed to 1 from its previous state, then update all other entities so they all have isDefault to 0
//else, means that this field is not changed, don't do anything
}
Or this must be done from the controller on every action?
I know that I can do it every time just if $this->isDefault is set to 1, but I would like to avoid it for performance and I might find it useful for some other scenarios as well.
Thanks in advance
You will have to write an Event Subscriber. Probably using an onFlush event, you can retrieve an Entities ChangeSet from the UnitOfWork to determine if a certain field has been updated and then do what ever you want.
There are some good behaviors for Doctrine2. Here is example of similar to your case.
I just don't really get this part
Say you clear a collection of tags by
calling $post->getTags()->clear(); and
then call $post->getTags()->add($tag).
This will not recognize tag being
already added before and issue two
database calls.
What 2 database calls will be issued? Delete all tags of the post then add one? Thats what I'd expect? Or will it be something else?
Did you try to call after the clear?
$entityManager->flush();
If this don't help try to remove one by one in foreach.