Relationship that was not marked cascade PERSIST

What Entity properties, when accessed through CUBA Studio may fix this problem? If not through CUBA, what will I need to add to my Java Class for the related Entities. I guess I don’t understand what cascade PERSIST really is.

IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST:

I recognize that this question has already been addressed, but not in English. Sorry.

This exception occurs when you save (persist or merge) an object with a reference to another object which is new (does not exists in the database). To avoid the error, such new object should be saved in the same persistence context, i.e. in the same transaction.

For example, you have two related entities: Customer and Order, and Order can contain a reference to Customer. Then, you have an editor screen for Order with the corresponding datasource. Imagine that when you edit a new Order, you programmatically create a new instance of Customer and set it to Order’s attribute. After that, you commit the screen. DataManager on middleware receives a CommitContext with the new Order which has the new Customer as a reference. It invokes EntityManager.persist(order), commits the transaction, and here the exception occurs - the Customer is not passed to the persistence context and there is no CASCADE relationship between Order and Customer.

The solution is to pass the new Customer together with the new Order. It can be done automatically if the screen contains a datasource for Customer - all datasources are saved on screen commit. Alternatively, the new Customer instance can be added to CommitContext in a DsContext.BeforeCommitListener.

Hope this helps.

2 Likes

Thank you!

Now, if Order referenced Customer, which referenced Address and Phone, how would I set up the DataSources?

They work individually, but I’m having trouble creating (in this example) an Order with a new Customer, with a new Addres and new Phone - all at the same time.

I’ve tried a few things, but nothing’s working yet.

The simplest and fully declarative solution would be to use nested datasources:

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd" caption="msg://editCaption"
        class="com.company.sample.web.order.OrderEdit" datasource="orderDs" focusComponent="fieldGroup"
        messagesPack="com.company.sample.web.order">
    <dsContext>
        <datasource id="orderDs" class="com.company.sample.entity.Order" view="order-edit-view">
            <datasource id="customerDs" property="customer">
                <datasource id="addressDs" property="address"/>
                <datasource id="phoneDs" property="phone"/>
            </datasource>
        </datasource>
    </dsContext>
    <layout expand="windowActions" spacing="true">
        <fieldGroup id="fieldGroup" datasource="orderDs">
            <column>
                <field id="date" width="250px"/>
                <field id="customer" width="250px"/>
                <field id="address" datasource="customerDs"/>
                <field id="phone" datasource="customerDs"/>
            </column>
        </fieldGroup>
        <frame id="windowActions" screen="editWindowActions"/>
    </layout>
</window>

Note that address and phone fields of the FieldGroup use different datasource from the one defined for the whole FieldGroup.

order-edit-view should contain all nested properties used in the screen datasources:

<view class="com.company.sample.entity.Order"
      extends="_local"
      name="order-edit-view">
    <property name="customer"
              view="_minimal">
        <property name="address"
                  view="_minimal"/>
        <property name="phone"
                  view="_minimal"/>
    </property>
</view>

The sample project is attached.

sample.zip (36.5K)

1 Like

A post was split to a new topic: Error on 2 level composition