Service and data manipulation error

Hi
I am trying to manipulate data in service and getting the following error:


java.lang.IllegalStateException: Cannot get unfetched attribute [article] from detached object com.mycompany.entity.SalesOrderLine-9ac085a4-1a69-e914-7e2b-7138eb0bb3af [detached].
	at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.throwUnfetchedAttributeException(UnitOfWorkValueHolder.java:322)
	at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:95)
	at com.mycompany.entity.SalesOrderLine._persistence_get_article(SalesOrderLine.java)
	at com.mycompany.entity.SalesOrderLine.getArticle(SalesOrderLine.java:80)
	at com.mycompany.service.PlanningServiceBean.runMRPSelectedSO(PlanningServiceBean.java:178)
	at com.mycompany.service.PlanningServiceBean.runMRP(PlanningServiceBean.java:142)
	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:497)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
	at com.haulmont.cuba.core.sys.TransactionalInterceptor.aroundInvoke(TransactionalInterceptor.java:37)
	at sun.reflect.GeneratedMethodAccessor404.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
	at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:74)
	at sun.reflect.GeneratedMethodAccessor139.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	at com.sun.proxy.$Proxy197.runMRP(Unknown Source)
	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:497)
	at com.haulmont.cuba.core.sys.remoting.LocalServiceInvokerImpl.invoke(LocalServiceInvokerImpl.java:84)
	at com.haulmont.cuba.web.sys.remoting.LocalServiceProxy$LocalServiceInvocationHandler.invoke(LocalServiceProxy.java:130)
	at com.sun.proxy.$Proxy60.runMRP(Unknown Source)
	at com.mycompany.gui.mrp.SalesorderMrp.onBtnCalculateAllClick(SalesorderMrp.java:33)
	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:497)
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:84)
	at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:48)
	at com.haulmont.cuba.web.gui.components.WebButton$1.buttonClick(WebButton.java:39)
	at sun.reflect.GeneratedMethodAccessor186.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1030)
	at com.vaadin.ui.Button.fireClick(Button.java:377)
	at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:54)
	at com.vaadin.ui.Button$1.click(Button.java:54)
	at sun.reflect.GeneratedMethodAccessor188.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:414)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79)
	at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.lambda$synchronizedHandleRequest$89(CubaVaadinServletService.java:307)
	at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler$$Lambda$35/1290123563.call(Unknown Source)
	at com.haulmont.cuba.web.sys.CubaVaadinServletService.withUserSession(CubaVaadinServletService.java:188)
	at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.synchronizedHandleRequest(CubaVaadinServletService.java:307)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:369)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:249)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:164)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.handleNotFiltered(CubaHttpFilter.java:108)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:95)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

the exception is originated here:


 if (soline.getArticle() != null) {

The full code in service:


@Override
    @Transactional
    public void runMRPSelectedSO(SalesOrder order) {

        try (Transaction tx = persistence.createTransaction()) {

            BigDecimal orderQuantity = BigDecimal.ZERO;
            BigDecimal baseQuantity = BigDecimal.ZERO;
            BigDecimal rejectRate = BigDecimal.ZERO;
            BigDecimal grossRequirements = BigDecimal.ZERO;
            BigDecimal wastageRate = BigDecimal.ZERO;
            BigDecimal componentRequirements = BigDecimal.ZERO;
            BigDecimal componentGrossRequirements = BigDecimal.ZERO;

            String sql = "delete from mydb$Mrp m where m.salesOrder.id = ?1";
            persistence.getEntityManager().createQuery(sql).setParameter(1,order.getId()).executeUpdate();

            TypedQuery<SalesOrderLine> solQuery = persistence.getEntityManager().createQuery("select l from mydb$SalesOrderLine l where l.salesOrder.id = ?1", SalesOrderLine.class);
            solQuery.setParameter(1, order.getId());

            for (SalesOrderLine soline : solQuery.getResultList()) {

                orderQuantity = new BigDecimal(soline.getQuantity().longValue());

                if (soline.getArticle() != null) {

                    TypedQuery<Article> query2 = persistence.getEntityManager().createQuery("select a from mydb$Article a where a.id = ?1", Article.class);
                    query2.setParameter(1, soline.getArticle().getId());


                    for (Article article : query2.getResultList()) {
                        //Get BOM of the article

                        TypedQuery<BillOfMaterial> bomQuery = persistence.getEntityManager().createQuery("select b from mydb$BillOfMaterial b where b.id = ?1", BillOfMaterial.class);
                        bomQuery.setParameter(1, article.getBillOfMaterial().getId());

                        for (BillOfMaterial bom : bomQuery.getResultList()) {

                            baseQuantity = new BigDecimal(bom.getBaseQuantity().longValue());
                            if (bom.getRejectPercentage() != null) {
                                rejectRate = new BigDecimal(bom.getRejectPercentage().longValue());
                                rejectRate = rejectRate.divide(new BigDecimal(100));
                            } else {
                                rejectRate = new BigDecimal(0);
                            }
                            TypedQuery<BillOfMaterialLines> bomlineQuery = persistence.getEntityManager().createQuery("select b from inteaccgms$BillOfMaterialLines b where b.billOfMaterial.id = ?1", BillOfMaterialLines.class);
                            bomlineQuery.setParameter(1, bom.getId());


                            //CALCULATION FORMULA
                            //====================================================
                
                            if (rejectRate.longValue() == 0) {
                                grossRequirements = new BigDecimal(soline.getQuantity().longValue());
                            } else {
                                grossRequirements = orderQuantity.divide(BigDecimal.ONE.subtract(rejectRate));
                            }
                            for (BillOfMaterialLines bomLines : bomlineQuery.getResultList()) {

                                //Calculate Material requirements before wastage
                                wastageRate = new BigDecimal(bomLines.getWastagePercentage().longValue());
                                wastageRate = wastageRate.divide(new BigDecimal(100));

     componentRequirements = grossRequirements.divide(bom.getBaseQuantity(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(bomLines.getQuantity().longValue()));
                                // a.divide(b, 2, RoundingMode.HALF_UP)

                                if (wastageRate.longValue() == 0) {
                                    componentGrossRequirements = componentRequirements;
                                } else {
                                    componentGrossRequirements = componentRequirements.divide(BigDecimal.ONE.subtract(wastageRate));
                                }
                                //save calculation
                                Mrp mrp = metadata.create(Mrp.class);
                                mrp.setSalesOrder(order);
                                mrp.setQuantity(componentGrossRequirements);
                                mrp.setMaterial(bomLines.getMaterial());
                                mrp.setArticle(bom.getArticle());
                                persistence.getEntityManager().persist(mrp);

                            }
                        }

                    }
                }
                tx.commit();
            }
        }
    }

Hi,
Which version of the platform do you use in the project?

That exception occurs when the attribute is not included into a view.
To fix the problem:

  1. Create a view which contains all required fields of the Article entity.
  2. Set the view to query in the service. As below:
 TypedQuery<SalesOrderLine> solQuery = persistence.getEntityManager().createQuery("select l from mydb$SalesOrderLine l where l.salesOrder.id = ?1", SalesOrderLine.class);
            solQuery.setParameter(1, order.getId());

            solQuery.setView(SalesOrderLine.class, "LineWithArticle-view");

            for (SalesOrderLine soline : solQuery.getResultList()) {
                       if (soline.getArticle() != null){....}
......

Hi Mortoza,
You have put tx.commit() inside “for” cycle, so on the second iteration your SalesOrderLine becomes detached and cannot lazily fetch the related object.

Thank you. this will help when dealing with multiple related entities with the use of View.