Persistency of embedded entity?

Here I created a small sample, you can see:

  1. If you fill the data to a property of embedded part, when creating a new main entity, then it works.
  2. If you create a new main entity without fill the embedded field, after creation done, you come back to update the main entity and give data to embedded field, then it won’t save it.
  3. I guess the main entity has no instance of embedded entity when you update it.
  4. I don’t wanna add more code to fix it in initNewItem or update/change listeners, more code means more error prone.

test-embedded.zip (246.9K)

And, even I did the trick as here: https://www.cuba-platform.com/discuss/t/embedded-entity-failure

set a new instance of embedded entity to main entity, it still treat it as null, so you can’t update these embedded field as the same.

I’m trying to find a decent way to correct this behaviour.

view:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<views xmlns="http://schemas.haulmont.com/cuba/view.xsd">
    <view class="com.company.testembedded.entity.MainEntity"
          extends="_local"
          name="mainEntity-view">
        <property name="embedded"
                  view="_local"/>
    </view>
</views>

datasource:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.company.testembedded.web.mainentity.MainEntityEdit"
        datasource="mainEntityDs"
        focusComponent="fieldGroup"
        messagesPack="com.company.testembedded.web.mainentity">
    <dsContext>
        <datasource id="mainEntityDs"
                    class="com.company.testembedded.entity.MainEntity"
                    view="mainEntity-view">
            <datasource id="embeddedDs"
                        property="embedded"/>
        </datasource>
    </dsContext>
    <dialogMode height="600"
                width="800"/>
    <layout expand="windowActions"
            spacing="true">
        <fieldGroup id="fieldGroup"
                    datasource="mainEntityDs">
            <column width="250px">
                <field id="name"/>
                <field id="embeddedName"
                       datasource="embeddedDs"/>
            </column>
        </fieldGroup>
        <frame id="windowActions"
               screen="editWindowActions"/>
    </layout>
</window>

editor:


package com.company.testembedded.web.mainentity;

import com.company.testembedded.entity.EmbeddedEntity;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.gui.components.AbstractEditor;
import com.company.testembedded.entity.MainEntity;

import javax.inject.Inject;

public class MainEntityEdit extends AbstractEditor<MainEntity> {

    @Inject
    private Metadata metadata;

    @Override
    protected void postInit() {
        if (getItem().getEmbedded() == null) {
            getItem().setEmbedded(metadata.create(EmbeddedEntity.class));
        }
    }

}

even this won’t work.

We just can’t utilize

Embedded Entity

properly. Is that bugged or just we have a wrong implementation?

The problem is that by default, ORM does not create an instance of embedded entity if all its attributes are null in the database. See https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Embeddable#Nullable_embedded_values

You can use the com.haulmont.cuba.core.entity.annotation.EmbeddedParameters annotation to change this to always have an instance, even if all attributes are null:


@Embedded
@AttributeOverrides({
    @AttributeOverride(name = "embeddedName", column = @Column(name = "EMBEDDED_EMBEDDED_NAME"))
})
@EmbeddedParameters(nullAllowed = false)
protected EmbeddedEntity embedded;