skip to Main Content

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.

  • TYPO3 v.11
  • Extbase
  • Fluid

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 venextDomainModelA

getter: @return venextDomainModelA

setter: @param venextDomainModelA
@return void

Annotations in the controller:

action: @param venextDomainModelA $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?

2

Answers


  1. 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:

    • Make sure your entity A is aware of entity B with a proper property and @var annotation.
    • Make sure you can access entity B as {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).
    • Try to avoid expressing the relationship on both entities unless you must do so. The right choice in your use case appears to be that A is aware of B but not vice versa. If you must have it on both sides, make absolutely sure that you configure the B side as the opposite side relation field in TCA. Expressing this relationship on B only makes sense if you have an actual use case where B can be handled separately from A (e.g. B has its own repository; is considered a separate aggregate root).
    Login or Signup to reply.
  2. apart from what Claus Due already explained.

    Extbase Persitance Mapping is somewhat unexpected as it uses TCA in the Background. so if there is no TCA Entry for a Property or Table. extbase is not able to Persist it. and it is often not "clear" that this is the reason. so make sure you have a valid TCA definition for your data.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search