My questions in advance:
How does Extbase decide if the given Object should be a transient entity or modified / persistent entity?
Is there any kind of Documentation on how Extbase maps (would you say mapping?) the form data into an Object?
I'm using Etxbase to create an extension for TYPO3.
I have a Model A with a relation to Model B.
Inside the database, B connected to A as "tx_vendor_ext_a {my_b int(11) unsigned
}".
A is displayed in the frontend via action controller and Fluid. AController has a List, Show, Edit, Delete and Create Action.
When I call my editAction(A $a) change some Values of A and Save (update Action(A $newA)) everything works fine. But when I want to Change Values of A.myB instead of updating myB Extbase is creating a new Object and persisting the new Object with a new UID.
I have a different Example where the child object is updated, not recreated. Debugging the parent in the update Action Shows (think of 'Kunde' as myB):
But when I debug the one not working, it shows (think of 'einstellungen' as myB):
Notice the transient entity flag.
My Fluid looks like this in both cases
<f:form action="update" name="a" object="{a}" >
<f:form.textfield property="myB.name" value="{myB.name}" id="myB-name" />
<f:form.submit value="Save" />
</f:form>
Annotations in the model class:
field : @var \ven\ext\Domain\Model\A
getter: @return \ven\ext\Domain\Model\A
setter: @param \ven\ext\Domain\Model\A
@return void
Annotations in the controller:
action: @param \ven\ext\Domain\Model\A $newA
I have to admit, I don't really know how Extbase is mapping the properties from the form into a domain object.
So These are my Questions:
How does Extbase decide if the given Object should be a transient entity or modified / persistent entity?
Is there any kind of Documentation on how Extbase maps (would you say mapping?) the form data into an Object?
Additionally: Where could I have made a mistake, causing Extbase to create a new Object instead of updating the old one?
The "transient" flag when you debug your entity only means that the entity is not yet persisted ($b->_isNew()
returns true
). It's not a special type of entity (there is only one such type) - it's solely about the persistence state. In other words: Extbase doesn't decide when an entity is transient vs. persistent - you make this decision by either persisting or not persisting your entity. Inferring from your description, you expect the flag to be "modified" meaning $b->_isDirty()
returns true
.
The information you provide about your property, getter and setter indicates a problem. If your entity B is only associated with entity A through a property on entity B, then B is not going to be thawed correctly when fetching A from persistence.
Judging by your template code:
<f:form.textfield property="myB.name" value="{myB.name}" id="myB-name" />
It appears that your B entity is somehow provided separately as variable {myB}
when the expected variable would be {a.myB}
. This could indicate that the problem I described above is relevant: if {a.myB}
does not yield the correct entity, then entity A is actually not aware of entity B and mapping would fail. By the way: specifying value="..."
is redundant since Extbase would extract the current value from the aggregate root entity (further indicating a problem if you have to specify it for a value to appear).
The solution therefore should be:
@var
annotation.{a.myB}
in the template (but remember that you should not need to, if the aggregate root works correctly and you reference the B entity's properties by their property path on the aggregate root).