Unfetched attribute from detached object

Hi everyone,

I am using an edit screen that inherit from a StandardEditor. When “saving and closing” the screen, I am getting the famous exception related to fetch-plan.

java.lang.IllegalStateException: Cannot get unfetched attribute [partyContacts] from detached object io.k.t.party.Organization-1 [detached].
at org.eclipse.persistence.internal.queries.EntityFetchGroup.onUnfetchedAttribute(EntityFetchGroup.java:100)
at io.jmix.eclipselink.impl.JmixEntityFetchGroup.onUnfetchedAttribute(JmixEntityFetchGroup.java:67)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.processUnfetchedAttribute(EntityManagerImpl.java:3027)
at io.k.t.party.Party._persistence_checkFetched(Party.java)
at io.k.t.party.Organization._persistence_get_partyContactPeoples(Organization.java)
at io.k.t.party.Organization.getPartyContactPeoples(Organization.java:174)
at io.jmix.core.entity.BaseEntityEntry.getAttributeValue(BaseEntityEntry.java:85)
at io.jmix.core.entity.EntityValues.getValue(EntityValues.java:100)
at io.jmix.eclipselink.impl.JpaDataStore$1.visit(JpaDataStore.java:530)
at io.jmix.core.MetadataTools.internalTraverseAttributesByFetchPlan(MetadataTools.java:1190)
at io.jmix.core.MetadataTools.traverseAttributesByFetchPlan(MetadataTools.java:933)
at io.jmix.eclipselink.impl.JpaDataStore.detachEntity(JpaDataStore.java:526)
at io.jmix.eclipselink.impl.JpaDataStore.beforeLoadTransactionCommit(JpaDataStore.java:305)
at io.jmix.core.datastore.AbstractDataStore.loadAllAfterSave(AbstractDataStore.java:449)
at io.jmix.core.datastore.AbstractDataStore.save(AbstractDataStore.java:236)
at io.jmix.core.impl.UnconstrainedDataManagerImpl.saveContextToStore(UnconstrainedDataManagerImpl.java:257)
at io.jmix.core.impl.UnconstrainedDataManagerImpl.save(UnconstrainedDataManagerImpl.java:216)
at io.jmix.ui.model.impl.DataContextImpl.commitToDataManager(DataContextImpl.java:710)
at io.jmix.ui.model.impl.DataContextImpl.performCommit(DataContextImpl.java:692)
at io.jmix.ui.model.impl.DataContextImpl.commit(DataContextImpl.java:653)
at io.jmix.ui.screen.StandardEditor.lambda$commitChanges$9(StandardEditor.java:427)
at io.jmix.ui.screen.StandardEditor.commitChanges(StandardEditor.java:455)
at io.jmix.ui.screen.StandardEditor.closeWithCommit(StandardEditor.java:616)
at io.k.t.party…web.screens.config.enterprise.EnterpriseEdit.closeWithCommit(EnterpriseEdit.java:238)
at io.jmix.ui.screen.StandardEditor.commitAndClose(StandardEditor.java:570)
at io.jmix.core.common.event.EventHub.publish(EventHub.java:170)
at io.jmix.ui.action.BaseAction.actionPerform(BaseAction.java:220)
at io.jmix.ui.component.impl.ButtonImpl.buttonClicked(ButtonImpl.java:75)
at io.jmix.ui.widget.JmixButton.fireClick(JmixButton.java:77)
at com.vaadin.ui.Button$1.click(Button.java:57)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115)
at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:442)
at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:407)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:275)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:83)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1636)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:465)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:147)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)

I don’t understand what is the problem as my fetch-plan of Enterprise entity already include the Organization and its partyContacts. Do you know what could be the issue ?

What I don’t understand is why on the closing the screen and the commit the fetch-plan is used ?

Best regards.
Samy

Hi Samy

Because the saved instance is loaded back and returned to the screen. Even when it’s closed, the saved instance is needed to set back into invoking screen, usually a browser.

Regarding the issue, could you reproduce it on a test project, or at least to attach the screen XML, fetch plan and entities code.

Also, please use “Preformatted text” (not “Blockquote”) when inserting code and exceptions here on the forum.

Regards,
Konstantin

Hi Konstantin,

I have tried to create a test project, but there it worked and was not able to reproduce the issue.

However I fixed the issue. The problem was that I defined the fetchPlan in the screen XML. At the same time I had the fetchPlans.xml that also defined the view. When I deleted the views definitions in the fetchPlans.xml, it worked.

I am wondering what is a best practice: defining the views within the XML screens or within the fetchPlans.xml? When one should use one over the other?

Thanks,
Samy

Hi.
It is a bug already present in Cuba
Unfetched attribute exception occurs in entity inspector when there is a transient attribute of related entity which uses persistent fields in accessor · Issue #2680 · cuba-platform/cuba (github.com)
I’m meeting that frequently in Jmix (for which, by the way, the Data Tools add-on is much weaker than the one for Cuba).
Apparently this 2020 bug is not fixed, and the workaround is not very well explained…

question: is there a way to access the fetch plan used by this entity inspector add-on, in order to add the missing field manually. In my example, displaying in the inspector a list of Detail fails:

IllegalStateException: Cannot get unfetched attribute [icTarget] from detached object com.choqnet.budget.entity.Team-a5127890-1f45-9ed0-9b32-f6ade918c33f [detached].

because of

 public String getSimplePlatform() {
        if (team==null || team.getIcTarget()==null) {
            return "Not assigned";
        }
        return team.getIcTarget();
    }

where simplePlatform is an attribute of Detail

Hi Oliver,

I think you are talking about a different problem. The original topic is not about Entity Inspector.

Could you describe your data model in more detail, and attach the whole stacktrace of the error?

Hi Konstantin.

Very late answer :wink:

If you create any Entity with an attribute that is an association with another entity and if you try to display it through the standard Entity Editor, it creates this "Unfetched attribute” error.

I can’t see how to assign a fetch plan (containing the associated entity) to this standard view: this should however be enough to solve the problem, I guess.

Have a nice day.

Something like this will load User.department.hrManager.lastName:

<fetchPlan extends="_base">
    <property name="department">
        <property name="name"/>
        <property name="hrManager">
            <property name="username"/>
            <property name="firstName"/>
            <property name="lastName"/>
        </property>
    </property>
</fetchPlan>

So it can be displayed as follows:

<form id="form" dataContainer="userDc">
    <textField id="deeplyNestedField" property="department.hrManager.lastName"/>

If this was a reply for me, I’d say that we don’t have access to the standard Entity Editor and cannot add a fetch plan. Access to deeply nested data fails.

Cheers.

Hi Olivier,

Sorry, I didn’t look at previous messages. Perhaps you mean the standard Entity Inspector. Try to add @DependsOnProperties annotation to your transient attribute.

Works well, thanks !