IllegalStateException: Cannot get unfetched attribute from detached object

I saw a lot of similar topics in the forum, but so far I can’t understand why this is happen.

A little bit more.

CardItem entity:

@NamePattern("The document in the following state: %s|cardState")
@Table(name = "DEMO_CARD_ITEM")
@Entity(name = "demo$CardItem")
public class CardItem extends StandardEntity {
	private static final long serialVersionUID = -3956149009965224251L;

	@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    public UUID getId() { 
    	return id; 
    }
	
	@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CARD_TYPE_ID")
    protected CardType cardType;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CARD_SUB_TYPE_ID")
    protected CardSubType cardSubType;
    
    @Column(name = "CARD_STATE", nullable = true)
    protected String cardState; 
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CARD_CREATION_DATE", nullable = false)
    protected Date cardCreationDate = new Date();
    
    @Column(name = "CARD_OUTCOME_NUMBER", nullable = false)
    protected String cardOutcomeNumber;
    
    @Column(name = "CARD_DATE", nullable = false)
    protected Date cardDate;

    @Column(name = "CARD_ORGANIZATION", nullable = false)
    protected String cardOrganization;

    @Column(name = "CARD_DELIVERY_METHOD", nullable = false)
    protected String cardDeliveryMethod;

    @Column(name = "CARD_ADDITIONAL_INFORMATION", nullable = true)
    protected String cardAdditionalInformation;
    
    @Column(name = "REGISTRATOR_NAME")
    protected String registratorName;
    
	// SKIPPED
}

CardSubType entity (sorry for the field names - see Hibernate - PropertyNotFoundException: Could not find a getter for):

@NamePattern("Подтип входящего документа: %s |a")
@Table(name = "DEMO_CARD_SUB_TYPE")
@Entity(name = "demo$CardSubType")
@Access(value = AccessType.FIELD)
public class CardSubType extends StandardEntity {
	private static final long serialVersionUID = -3558412722346178348L;

	@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    public UUID getId() { 
    	return id; 
    }
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CARD_TYPE_ID")
    protected CardType cardType;

    @Column(name = "CARD_TYPE_NAME", nullable = false)
    @Access(value = AccessType.FIELD)
	protected String a;

    @Column(name = "CARD_TYPE_ITEM", nullable = false)
    @Access(value = AccessType.FIELD)
	protected Integer b;

	// SKIPPED
}

CardType entity (sorry for the field names - see Hibernate - PropertyNotFoundException: Could not find a getter for
):

@NamePattern("Тип входящего документа: %s |b")
@Table(name = "DEMO_CARD_TYPE")
@Entity(name = "demo$CardType")
@Access(value = AccessType.FIELD)
public class CardType extends StandardEntity {
	private static final long serialVersionUID = -2234911097509892559L;

	@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    public UUID getId() { 
    	return id; 
    }
	
    @Column(name = "CARD_TYPE_ITEM", nullable = false)
    @Access(value = AccessType.FIELD)
    protected Integer a;
    
    @Column(name = "CARD_TYPE_NAME", nullable = false)
    @Access(value = AccessType.FIELD)
    protected String b;

	// SKIPPED
}

My card-item-browse.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://browseCaption"
        class="com.client.web.item.CardItemBrowse"
        focusComponent="documentsTable"
        lookupComponent="documentsTable"
        messagesPack="com.client.web.item">
    <dsContext>
        <collectionDatasource id="cardItemDs" class="com.client.entity.CardItem" view="_local">
            <query>
                <![CDATA[select c from demo$CardItem c]]>
            </query>
        </collectionDatasource>
    </dsContext>
    
    <layout expand="documentsTable" spacing="true">
        <filter id="filter" applyTo="documentsTable" datasource="cardItemDs">
            <properties include=".*"/>
        </filter>
        
        <table id="documentsTable" width="100%">
            <actions>
                <action id="create"/>
                <action id="remove"/>
			</actions>
        
            <columns>
                <column id="cardState"/>
                <column id="cardType"/>
                <column id="cardSubtype"/>
                <column id="cardOutcomeNumber"/>
                <column id="cardDate"/>
                <column id="cardOrganization"/>
                <column id="cardDeliveryMethod"/>
                <column id="cardAdditionalInformation"/>
                <column id="registratorName"/>
            </columns>
            <rows datasource="cardItemDs"/>
            <rowsCount/>
            <buttonsPanel id="buttonsPanel" alwaysVisible="true">
                <button id="createBtn" action="documentsTable.create"/>
                <button id="removeBtn" action="documentsTable.remove"/>
            </buttonsPanel>
			</table>        	
		</layout>
</window>

CardItemBrowse controller:

public class CardItemBrowse extends AbstractLookup {
    @Inject
    private CollectionDatasource<CardItem, UUID> cardItemDs;
	
    @Inject
    private Metadata metadata;
    
    @Named("documentsTable.create")
    private CreateAction documentsTableEdit;
    
	@Override
    public void init(Map<String, Object> params) {
		//documentsTableEdit.setAfterCommitHandler(entity -> cardItemDs.refresh());
	}
	
	public void create(Component component) {
		com.client.entity.CardItem item = 
				metadata.create(com.client.entity.CardItem.class);
		
		openEditor("demo$CardItem.edit", item, WindowManager.OpenType.NEW_TAB);
	}
}

card-item-edit.xml screen:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.client.web.item.CardItemEdit"
        datasource="cardItemDs"
        focusComponent="cardItemsGroup"
        lookupComponent="cardItemsGroup"
        messagesPack="com.client.web.item">
    
     <dsContext>
        <datasource id="cardItemDs" class="com.client.entity.CardItem" view="_local"/>
        	<collectionDatasource id="cardTypeDs" class="com.client.entity.CardType">
            <query>
                <![CDATA[select e from demo$CardType e]]>
            </query>
        </collectionDatasource>
        	<collectionDatasource id="cardSubTypeDs" class="com.client.entity.CardSubType">
            <query>
                <![CDATA[select s from demo$CardSubType s where s.cardType.id = :ds$cardTypeDs]]>
            </query>
        </collectionDatasource>
    </dsContext>
    
    <actions>
        <action id="save" caption="mainMsg://actions.Ok" invoke="save" />
        <action id="cancel" caption="mainMsg://actions.Cancel" invoke="cancel" />
    </actions>
    
    <dialogMode forceDialog="true" width="AUTO"/>
	<layout spacing="true">
        <fieldGroup id="cardItemsGroup" datasource="cardItemDs">
            <column width="500px">
                <field id="cardCreationDate" property="cardCreationDate" editable="false" datasource="cardItemDs" />
                <field id="cardTypeField" caption="Тип документа">
            		<lookupPickerField id="cardType" datasource="cardItemDs" property="cardType" optionsDatasource="cardTypeDs"/>
				</field>
                <field id="cardSubTypeField" caption="Подтип документа">
                	<lookupPickerField id="cardSubType" datasource="cardItemDs" property="cardSubType" optionsDatasource="cardSubTypeDs"/>
				</field>
                <field id="cardOutcomeNumber" datasource="cardItemDs" property="cardOutcomeNumber"/>
                <field id="cardDate" datasource="cardItemDs" property="cardDate"/>
                <field id="cardOrganization" datasource="cardItemDs" property="cardOrganization"/>
                <field id="cardDeliveryMethod" datasource="cardItemDs" property="cardDeliveryMethod"/>
                <field id="cardAdditionalInformation" datasource="cardItemDs" property="cardAdditionalInformation"/>
                <field id="registratorName" datasource="cardItemDs" property="registratorName"/>
            </column>
        </fieldGroup>
		<hbox id="actionsPane" spacing="true" visible="true">
			<button id="saveBtn" action="save"/>
			<button id="cancelBtn" action="cancel"/>
		</hbox>
    </layout>
</window>

CardItemEdit controller:

public class CardItemEdit extends AbstractEditor<CardItem> {
	
	@Named("cardItemsGroup.cardCreationDate")
    private Field cardCreationDate;
    
	@Inject
    private LookupField cardType;
    @Inject
    private LookupField cardSubType;
    
    @Named("cardItemsGroup.cardOutcomeNumber")
    private Field cardOutcomeNumber;
    
    @Named("cardItemsGroup.cardDate")
    private Field cardDate;
    
    @Named("cardItemsGroup.cardOrganization")
    private Field cardOrganization;
    
    @Named("cardItemsGroup.cardDeliveryMethod")
    private Field cardDeliveryMethod;
    
    @Named("cardItemsGroup.cardAdditionalInformation")
    private Field cardAdditionalInformation;
    
    @Named("cardItemsGroup.registratorName")
    private Field registratorName;

    @Inject
    private CardItemService cardItemService;
    
    public void save() {
    	CardItem cardItem = new CardItem();
    	cardItem.setCardType(cardType.getValue());
    	cardItem.setCardSubType(cardSubType.getValue());
    	cardItem.setCardOutcomeNumber(cardOutcomeNumber.getValue());
    	cardItem.setCardOrganization(cardOrganization.getValue());
    	cardItem.setCardDeliveryMethod(cardDeliveryMethod.getValue());
    	cardItem.setCardDate(cardDate.getValue());
    	cardItem.setCardCreationDate(cardCreationDate.getValue());
    	cardItem.setCardAdditionalInformation(cardAdditionalInformation.getValue());
    	cardItem.setRegistratorName(registratorName.getValue());
    	
    	cardItemService.saveCardItem(cardItem);
    }
}

Middleware service CardItemServiceBean:

@Service(CardItemService.NAME)
public class CardItemServiceBean implements CardItemService {

    @Inject
    private Persistence persistence;
	
	@Override
	public UUID saveCardItem(CardItem cardItem) {
        try(Transaction tx = persistence.createTransaction()) {
            persistence.getEntityManager().persist(cardItem);
            tx.commit();
        }
        return cardItem.getId();
	}

	@Override
	public List<CardItem> loadCardItems() {
		// TODO Auto-generated method stub
		return null;
	}
}

I can create cards - all OK, without exception. But when I open the screen with a table to view - card-item-browse - the following message always appears:

IllegalStateException: Cannot get unfetched attribute [cardType] from detached object com.client.entity.CardItem-5284ac16-dfaa-8b01-48d3-3549dded79f2 [detached].

Details:

java.lang.IllegalStateException: Cannot get unfetched attribute [cardType] from detached object com.client.entity.CardItem-5284ac16-dfaa-8b01-48d3-3549dded79f2 [detached].
	at org.eclipse.persistence.internal.queries.EntityFetchGroup.onUnfetchedAttribute(EntityFetchGroup.java:98)
	at com.haulmont.cuba.core.sys.persistence.CubaEntityFetchGroup.onUnfetchedAttribute(CubaEntityFetchGroup.java:61)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.processUnfetchedAttribute(EntityManagerImpl.java:2846)
	at com.haulmont.chile.core.model.impl.AbstractInstance._persistence_checkFetched(AbstractInstance.java)
	at com.client.entity.CardItem._persistence_get_cardType(CardItem.java)
	at com.client.entity.CardItem.getCardType(CardItem.java:140)
	at sun.reflect.GeneratedMethodAccessor150.invoke(Unknown Source)
	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:72)
	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.chile.core.model.utils.InstanceUtils.getValueEx(InstanceUtils.java:139)
	at com.haulmont.cuba.web.gui.data.PropertyWrapper.getValue(PropertyWrapper.java:76)
	at com.haulmont.cuba.web.gui.components.WebAbstractTable$TablePropertyWrapper.getValue(WebAbstractTable.java:2035)
	at com.haulmont.cuba.web.gui.data.PropertyWrapper.getFormattedValue(PropertyWrapper.java:149)
	at com.haulmont.cuba.web.gui.components.WebAbstractTable$TablePropertyWrapper.getFormattedValue(WebAbstractTable.java:2021)
	at com.haulmont.cuba.web.toolkit.ui.CubaTable.formatPropertyValue(CubaTable.java:240)
	at com.haulmont.cuba.web.toolkit.ui.CubaTable.getPropertyValue(CubaTable.java:200)
	at com.vaadin.ui.Table.parseItemIdToCells(Table.java:2387)
	at com.vaadin.ui.Table.getVisibleCellsNoCache(Table.java:2237)
	at com.vaadin.ui.Table.refreshRenderedCells(Table.java:1780)
	at com.vaadin.ui.Table.refreshRowCache(Table.java:2687)
	at com.vaadin.ui.Table.containerItemSetChange(Table.java:4616)
	at com.haulmont.cuba.web.gui.data.CollectionDsWrapper.fireItemSetChanged(CollectionDsWrapper.java:109)
	at com.haulmont.cuba.web.gui.data.CollectionDsWrapper$ContainerDatasourceCollectionChangeListener.collectionChanged(CollectionDsWrapper.java:270)
	at com.haulmont.bali.events.EventRouter.fireEvent(EventRouter.java:45)
	at com.haulmont.cuba.gui.data.impl.CollectionDsListenersWrapper.collectionChanged(CollectionDsListenersWrapper.java:53)
	at com.haulmont.cuba.web.gui.components.WebAbstractTable$TableCollectionDsListenersWrapper.collectionChanged(WebAbstractTable.java:3028)
	at com.haulmont.cuba.gui.data.impl.WeakCollectionChangeListener.collectionChanged(WeakCollectionChangeListener.java:41)
	at com.haulmont.bali.events.EventRouter.fireEvent(EventRouter.java:45)
	at com.haulmont.cuba.gui.data.impl.AbstractCollectionDatasource.fireCollectionChanged(AbstractCollectionDatasource.java:371)
	at com.haulmont.cuba.gui.data.impl.CollectionDatasourceImpl.afterRefresh(CollectionDatasourceImpl.java:198)
	at com.haulmont.cuba.gui.data.impl.CollectionDatasourceImpl.refresh(CollectionDatasourceImpl.java:163)
	at com.haulmont.cuba.gui.data.impl.CollectionDatasourceImpl.refresh(CollectionDatasourceImpl.java:119)
	at com.haulmont.cuba.gui.data.impl.CollectionDatasourceImpl.setSuspended(CollectionDatasourceImpl.java:722)
	at com.haulmont.cuba.gui.data.impl.DsContextImpl.resumeSuspended(DsContextImpl.java:84)
	at com.haulmont.cuba.gui.WindowManager.afterShowWindow(WindowManager.java:1159)
	at com.haulmont.cuba.web.WebWindowManager.showWindow(WebWindowManager.java:419)
	at com.haulmont.cuba.gui.WindowManager.openWindow(WindowManager.java:756)
	at com.haulmont.cuba.web.WebWindowManager.openWindow(WebWindowManager.java:155)
	at com.haulmont.cuba.gui.config.MenuCommand$ScreenCommand.run(MenuCommand.java:181)
	at com.haulmont.cuba.gui.config.MenuCommand.execute(MenuCommand.java:76)
	at com.haulmont.cuba.web.sys.MenuBuilder.lambda$createMenuBarCommand$0(MenuBuilder.java:176)
	at com.haulmont.cuba.web.gui.components.mainwindow.WebAppMenu$MenuItemImpl.lambda$setCommand$2434f46b$1(WebAppMenu.java:342)
	at com.vaadin.ui.MenuBar.changeVariables(MenuBar.java:212)
	at com.vaadin.server.communication.ServerRpcHandler.changeVariables(ServerRpcHandler.java:623)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:470)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:413)
	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:300)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:191)
	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:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	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:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	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)

If I deleted these fields from the card-item-browse.xml descriptor:

<column id="cardType"/>
<column id="cardSubtype"/>

Then everything works fine.

What could be the problem?

I would be very grateful for the information. Thanks to all.

What helped: Views

I added the following in view.xml:

<views xmlns="http://schemas.haulmont.com/cuba/view.xsd">
  <view class="com.client.entity.CardItem"
        name="card-item-browse"
        extends="_local">
      <property name="cardType" view="_minimal"/>
      <property name="cardSubType" view="_minimal"/>
  </view>
</views>

Now everything is ok.

1 Like