phptypo3fluidextbasetypo3-11.x

Typo3 Extbase - In which cases are Objects transient entities? Why is my entity object not updated but recreated?


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): Debug Screen section Child object - 1

But when I debug the one not working, it shows (think of 'einstellungen' as myB): Debug Screen section Child object - 2

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?


Solution

  • 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: