Error on 2 level composition

Probably is a similar problem:

I have a collection (part of a father Entity) of persisted entity (say Assignments) and I want to create a second level of entity (say Payments Assignment(1)<-Payment(n)) programmatically.

For this relation (a 2 level composition I configured datasources and create payments programmatically).

For each assignment I create another entity which conteains a collecion of the same assignments.

So for each assigment::

create Payment and add to payments collection in Assignment
create Wage Calculation and add Assignment in a 1 <- many composition

persist assignment+ payments (2 level composition Datasource)
persist all WageCalculation Objects containing same entity Tree

I used before commit listener for Wage Calculation. I get this error on 2 level composition:
(verified view). Why?

Thank you inadvance,
Fabrizio

Error:


java.lang.IllegalStateException: Cannot get unfetched attribute [employeePayments] from detached object pro.sysonline.contacts.entity.InvoiceArtistAssignment-c54d616d-116d-ccea-248d-2138b4361a28 [detached].
	at org.eclipse.persistence.internal.queries.EntityFetchGroup.onUnfetchedAttribute(EntityFetchGroup.java:98)
	at com.haulmont.cuba.core.sys.persistence.CubaEntityFetchGroup.onUnfetchedAttribute(CubaEntityFetchGroup.java:74)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.processUnfetchedAttribute(EntityManagerImpl.java:2846)
	at com.haulmont.chile.core.model.impl.AbstractInstance._persistence_checkFetched(AbstractInstance.java)
	at pro.sysonline.contacts.entity.InvoiceArtistAssignment._persistence_get_employeePayments(InvoiceArtistAssignment.java)
	at pro.sysonline.contacts.entity.InvoiceArtistAssignment.getEmployeePayments(InvoiceArtistAssignment.java:95)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.haulmont.chile.core.model.utils.MethodsCache.invokeGetter(MethodsCache.java:71)
	at com.haulmont.chile.core.model.impl.AbstractInstance.getValue(AbstractInstance.java:102)
	at com.haulmont.cuba.core.entity.BaseGenericIdEntity.getValue(BaseGenericIdEntity.java:139)
	at com.haulmont.cuba.gui.data.impl.CollectionPropertyDatasourceImpl.lambda$initParentDsListeners$0(CollectionPropertyDatasourceImpl.java:91)
	at com.haulmont.bali.events.EventRouter.fireEvent(EventRouter.java:45)
	at com.haulmont.cuba.gui.data.impl.AbstractDatasource.fireItemChanged(AbstractDatasource.java:283)
	at com.haulmont.cuba.gui.data.impl.CollectionPropertyDatasourceImpl.setItem(CollectionPropertyDatasourceImpl.java:234)
	at com.haulmont.cuba.gui.data.impl.CollectionPropertyDatasourceImpl.internalAddItem(CollectionPropertyDatasourceImpl.java:325)
	at com.haulmont.cuba.gui.data.impl.CollectionPropertyDatasourceImpl.addItem(CollectionPropertyDatasourceImpl.java:293)
	at pro.sysonline.contacts.web.invoice.InvoiceEdit.makeEmployeeDeposit(InvoiceEdit.java:2463)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:92)
	at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:46)
	at com.haulmont.cuba.web.gui.components.WebButton.lambda$new$61446b05$1(WebButton.java:38)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1037)
	at com.vaadin.ui.Button.fireClick(Button.java:377)
	at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:69)
	at com.vaadin.ui.Button$1.click(Button.java:54)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:119)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:444)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:409)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1435)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:361)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:324)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:210)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:107)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

Datasources:

2 Level Composition DsContext

<datasource id="invoiceDs"
                    class="pro.sysonline.contacts.entity.Invoice"
                    view="invoice-all-view">
            <collectionDatasource id="rowsDs"
                                  property="rows"/>
            <collectionDatasource id="invoiceDocDs"
                                  property="infoDocs"/>
            <collectionDatasource id="assignmentDs"
                                  property="artistAssignment">            2 Level Composition
                <collectionDatasource id="empPaymentsDs"
                                      property="employeePayments"/>       2 Level Composition
            </collectionDatasource>
            <collectionDatasource id="paymentDs"
                                  property="payments"/>
        </datasource>

View:

    <view class="pro.sysonline.contacts.entity.InvoiceArtistAssignment"
          extends="_local"
          name="InvoiceArtistAssignment-all-view">
        <property name="invoice"
                  view="_minimal">
            <property name="date"/>
            <property name="initial_date"/>
            <property name="fullNR"/>
            <property name="year"/>
            <property name="number"/>
        </property>
        <property name="person"
                  view="_minimal"/>
        <property name="wageCalculation"
                  view="_minimal">
            <property name="description"/>
            <property name="month"/>
            <property name="year"/>
            <property name="date"/>
            <property name="approved"/>
        </property>
        <property name="residual_value"/>
        <property name="employeePayments"
                  view="_minimal">
            <property name="paymentAccountability"/>
            <property name="insDate"/>
            <property name="value"/>
            <property name="payMode"/>
            <property name="payDate"/>
            <property name="payType"/>
            <property name="month"/>
            <property name="year"/>
            <property name="payed"/>
            <property name="invoiceArtistAssignment"
                      view="_minimal"/>
        </property>
    </view>        

Extract Code (in Editor, portion of method called with invoke in a Button):

if (i.getArtistAssignment() != null) {
for (InvoiceArtistAssignment as : i.getArtistAssignment()) {

            as = dataManager.load(InvoiceArtistAssignment.class).id(as.getId()).view("InvoiceArtistAssignment-all-view").one();
            WageCalculation wc = wageCalculationService.findCalculation(as.getPerson(),as.getMonth(),as.getYear());
            // If not found create it
            if (wc == null) {
                wc = metadata.create(WageCalculation.class);
            }

            // Configure Wage Calculation
            wc.setArtist(as.getPerson());
            wc.setMonth(as.getMonth());
            wc.setYear(as.getYear());
            as.setWageCalculation(wc);
            if (wc.getInvoiceAssignments() == null) {
                wc.setInvoiceAssignments(new ArrayList<InvoiceArtistAssignment>());
            }
            wc.getInvoiceAssignments().add(as);
            wcSave.add(wc);


            // Eventually Initialize
            if (empPaymentsDs.getItems().isEmpty()) {
                List<EmpPayment> empoyeePayments = new ArrayList<EmpPayment>();
                as.setEmployeePayments(empoyeePayments);
            }

            // Add Payments to Assignment
            BigDecimal epValue  = as.getResidual_value().multiply(artist_deposit_share);
            EmpPayment ep = metadata.create(EmpPayment.class);
            ep.setPayType(PayType.deposit);
            ep.setPayDate(null);
            ep.setPayMode(PayMethod.wiretranfer);
            ep.setDescription(as.getMonth() + " " + as.getYear() + " - " +  as.getPerson().getLastName() + " " + as.getPerson().getFirstName() + " - " +  i.getFullNR().trim() + " " + i.getDescription().trim());
            ep.setValue(epValue);
            ep.setInsDate(today);
            ep.setYear(as.getYear());
            ep.setMonth(as.getMonth());
            ep.setPaymentAccountability(as.getAccountability());
            ep.setInvoiceArtistAssignment(as);
            as.getEmployeePayments().add(ep);
            empPaymentsDs.addItem(ep);     <<<<< Exception Here
        }
before commit for WageCalculation Objects:

@Inject
protected DsContext dsContext;

@Override
init() {

dsContext.addBeforeCommitListener(context -> {
if ((wcSave != null) && (!wcSave.isEmpty())) {
for (WageCalculation wc : wcSave) {
context.getCommitInstances().add(wc);
}
}
});

}

Hi,

You may want to check if you use proper views not only for the entities in your “main” collection, but also for lookup fields.

Unfetched attribute exception is always caused by improper views use. Please debug the code in the IDE to see which view is applied or use EntityStates.isLoadedWithView() for verification.

Thank you I’ll checked if view contains all required property, but I’ try EntityStates, as you suggest.

Consider that many modifications are made programammatically, without using datasources because I should have to create 1 datasource for each new entity in iteration so I tried to save them using before commit listener and DsContext.
Any hint how to find example about complex tree of entity managed in this way.
Thank you again.
Fabrizio