Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Lazy Loading

  1. #1
    Join Date
    May 2006
    Posts
    112

    Default Lazy Loading

    Helllo,

    I am baffled by this obscure behaviour. We have a flow for which does adding/editing an item.

    When I load the application and try to edit (lets say item A) it works fine with no errors. Next I add a new item and that works well too. But if I try to edit item A again I get a Lazy Loading error.

    If I restart tomcat and try and edit Item A it starts working again.

    So in short I cannot edit an item after I have added a new item. But I can keep on adding new items with no trouble.

    Can any one tell me why does this happen.

    ~s.

  2. #2
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    if you can posy your stacktrace
    it would help

    So in short I cannot edit an item after I have added a new item. But I can keep on adding new items with no trouble.
    if you can post some code to try to follow your logic, it would be great

    regards
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  3. #3
    Join Date
    May 2006
    Posts
    112

    Default

    It breaks in the walk though the images collection


    Code:
        public Event setupReferenceData(RequestContext context) throws Exception
        {
    	AcctItemForm form = (AcctItemForm) getFormObject(context);
    	HttpServletRequest request = ((ServletExternalContext) context
    		.getExternalContext()).getRequest();
    	this.setAcctItem(new AcctItemForm());
    	Long id = ServletRequestUtils.getLongParameter(request, "acctItemId",
    		new Long(0));
    	log.debug("id :" + id);
    	if (id.intValue() > 0)
    	{
    	    try
    	    {
    		
    		form.setAcctItem(acctItemService.load(id));
    		log.debug("gets in here");
    		
    	    }
    	    catch (Exception e)
    	    {
    		// bad id
    	    }
    	}
    	else
    	{
    	    log.debug("new Item gets in here");
    	    this.setNewItem(true);
    	}
    	String acctType = ServletRequestUtils.getStringParameter(request,
    		"acctType", "");
    	
    	if (this.isNewItem())
    	{
    	    String message = "";
    	    if (acctType.length() < 1)
    		message = "No Account Type specified";
    	    try
    	    {
    		log.debug("gets in here new item reference");
    		AccountItemType acctItemType = acctItemTypeService
    			.get(acctType);
    		form.getAcctItem().setAcctItemType(acctItemType);
    		form.getAcctItem().setPkgType(AccountItemPkgType.NONE);
    		log.debug("new type gets in here");
    	    }
    	    catch (Exception e)
    	    {
    		message = "Invalid Account Type";
    	    }
    	    context.getFlowScope().put("message", message);
    	}
    	
    	log.debug("validator" + this.getValidator());
    	
    	// avoiding lazy loading in files
    	Hibernate.initialize(form.getAcctItem().getImages());
    	if(form.getAcctItem().getImages() != null)
    	{	    
    	    log.debug("gets in images setuphere");
    	    log.debug(form.getAcctItem().getName());
                for (AccountItemAttachement f : form.getAcctItem().getImages())
                {
                    f.getId();
                    f.getFile();
                    f.getFile().getId();
                    f.getFile().getName();
                    f.getFile().getNormalUri();
                }
    	}
    	else
    	{
    	    form.getAcctItem().setImages(new TreeSet<AccountItemAttachement>());
    	}
    
    
    //other collection walk-throughs
    	context.getFlowScope().put("acctItem", form);
    	return success();
    	
        }
    Stack Trace
    Code:
     
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.engine.ActionExecutionException: Exception thrown executing [AnnotatedAction@106fc22 targetAction = com.netmemex.netmx.web.AcctItemFormAction@18bd6f9, attributes = map['method' -> 'setupReferenceData']] in state 'null' of flow 'accountItem-flow' -- action execution attributes were 'map['method' -> 'setupReferenceData']'; nested exception is org.hibernate.HibernateException: collection is not associated with any session
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:487)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:430)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    .....
    
    root cause
    
    org.springframework.webflow.engine.ActionExecutionException: Exception thrown executing [AnnotatedAction@106fc22 targetAction = com.netmemex.netmx.web.AcctItemFormAction@18bd6f9, attributes = map['method' -> 'setupReferenceData']] in state 'null' of flow 'accountItem-flow' -- action execution attributes were 'map['method' -> 'setupReferenceData']'; nested exception is org.hibernate.HibernateException: collection is not associated with any session
    	org.springframework.webflow.engine.ActionExecutor.execute(ActionExecutor.java:68)
    	org.springframework.webflow.engine.ActionList.execute(ActionList.java:160)
    	org.springframework.webflow.engine.Flow.start(Flow.java:556)
    	org.springframework.webflow.engine.impl.RequestControlContextImpl.start(RequestControlContextImpl.java:196)
    	org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:189)
    	org.springframework.webflow.executor.FlowExecutorImpl.launch(FlowExecutorImpl.java:206)
    	org.springframework.webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:131)
    	org.springframework.webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:172)
    	org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:857)
    	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:475)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:430)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    	........
    root cause
    
    org.hibernate.HibernateException: collection is not associated with any session
    org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)
    	org.hibernate.Hibernate.initialize(Hibernate.java:309)
    	com.netmemex.netmx.web.AcctItemFormAction.setupReferenceData(AcctItemFormAction.java:1380)
    	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	java.lang.reflect.Method.invoke(Method.java:597)
    	org.springframework.webflow.util.DispatchMethodInvoker.invoke(DispatchMethodInvoker.java:103)
    	org.springframework.webflow.action.MultiAction.doExecute(MultiAction.java:136)
    	org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:203)
    	org.springframework.webflow.engine.AnnotatedAction.execute(AnnotatedAction.java:154)
    	org.springframework.webflow.engine.ActionExecutor.execute(ActionExecutor.java:61)
    	org.springframework.webflow.engine.ActionList.execute(ActionList.java:160)
    	org.springframework.webflow.engine.Flow.start(Flow.java:556)
    	org.springframework.webflow.engine.impl.RequestControlContextImpl.start(RequestControlContextImpl.java:196)
    	org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:189)
    	org.springframework.webflow.executor.FlowExecutorImpl.launch(FlowExecutorImpl.java:206)
    	org.springframework.webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:131)
    	org.springframework.webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:172)
    	org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:857)
    	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:475)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:430)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    .....

  4. #4

    Default

    form.setAcctItem(acctItemService.load(id));
    Does acctItemService.load(id) method returns a copy of the the AcctItem fetched from the database?

    I guess the AcctItem object you returned is the AcctItem fetched from the database. I suggest you return a new instance containing a copy of the fields (primitive data type not object fields) to the caller.
    Last edited by newbix; Oct 10th, 2007 at 07:36 PM.

  5. #5
    Join Date
    May 2006
    Posts
    112

    Default

    thanks for your reply.

    "Loading a new instance" I was hoping hibernate would take care of that. If it is cached it will get it from there if not then hit the db. The service layer calls up the dao layer to fetch it from the db.

    so for eg the service layer call would eventually end up calling a function in the DAO class which extends HibernateDaoSupport like

    this.getHibernateTemplate.get(AcctItem.class, new Long(1));

    If that is not the case then how does one discriminate between what calls are to get a fresh copy from the db and which ones are to be returned from the cache????



    ~s.

  6. #6

    Default

    Hi some one,

    this.getHibernateTemplate.get(AcctItem.class, new Long(1));
    It's fine to invoke this line that is if AcctItem has no relation to other objects.

    Could you post the AcctItem class and the mapping (.hbm) of it so that I could take a look at it. It think it's a hibernate issue.
    Last edited by newbix; Oct 10th, 2007 at 07:35 PM.

  7. #7
    Join Date
    May 2006
    Posts
    112

    Default

    thanks for your help. the pojo class has only the getter and setters for the hbm there are no convienience classes or anything of that sort. So i just put up the hbm


    Code:
    hibernate-mapping package="com.netmemex.netmx.domain.transactions">
    <!--  maps to MX_ACCT_ITEM -->
    	<class name="AccountItem" table="MX_ACCT_ITEM">
    		<id name="id" column="AI_ID" type="long" access="field">
    			<generator class="increment"/>
    		</id>
    		
    		<set name="acctCatLink" table ="MX_ACCT_ITEM_CAT" inverse="true"  cascade="all, delete-orphan">
    			<key column="AI_ID" not-null="true"/>
    			<one-to-many class="com.netmemex.netmx.domain.transactions.AccountItemCategory"/>
    		</set>
    		
    		<many-to-one name="acctItemType" class="com.netmemex.netmx.domain.lookup.AccountItemType" column="AI_TYPE_CODE"/>
    		
    		<property name="acctPriceClass" column="ACCT_PRICE_CLASS" />
    		<property name="active" column="AI_ACTIVE_IND" type="yes_no"/>
    		
    		<set name ="attachements" table="MX_ACCT_ITEM_ATTACHMENT" lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID"/>
    			<one-to-many class="com.netmemex.netmx.domain.transactions.AccountItemAttachement" />
    		</set>
    		
    		<property name="availOnline" column="AI_AVAILABLE_ONLINE_IND" type="yes_no"/>
    		<property name="code" column="AI_CODE" />
    		<property name="cost" column="AI_COST" type="float" />
    		<property name="createDate" column="AI_CREATE_DATE" type="date" />
    		
    		<many-to-one name="createUser" class="com.netmemex.netmx.domain.Master" column="AI_CREATE_MAST_ID" />
    		
    		<property name="creditCard" column="AI_CC_IND" type="yes_no"/>
    		
    		<property name="deferable" column="AI_DEFERMENT_IND" type="yes_no"/>
    		<property name="deferPeriods" column="AI_DEF_PERIODS" type="int" />
    		<property name="desc" column="AI_DESC" />		
    		
    		<set name ="docs" table="MX_ACCT_ITEM_ATTACHMENT" lazy="true" where ="(select f.file_type from mx_file f where f.file_id = file_id) = 'PROD_DOC'"
    			cascade="save-update">
    			<key column ="AI_ID"/>
    			<one-to-many class="com.netmemex.netmx.domain.transactions.AccountItemAttachement" />
    		</set>
    		
    		<property name="duesMonths" column="AI_DUES_MONTHS" type="int" />
    		<property name="fiscal" column="AI_FISCAL_IND" type="yes_no"/>
    		
    		<set name ="genLedger"
    				table="MX_ACCT_ITEM_GL"
    				lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID"/>
    			<many-to-many class ="com.netmemex.netmx.domain.transactions.GenLedger" column="GL_ID"/>
    		</set>
    		<set name ="images" table="MX_ACCT_ITEM_ATTACHMENT" lazy="true" where ="(select f.file_type from mx_file f where f.file_id = file_id) = 'PROD_IMG'"
    			cascade="save-update">
    			<key column ="AI_ID"/>
    			<one-to-many class="com.netmemex.netmx.domain.transactions.AccountItemAttachement" />
    		</set>
    		
    		<property name="inventoryLocation" column="AI_INVENTORY_LOCATION" />
    		<property name="inventoryOrderDate" column="AI_INVENTORY_ORDER_DATE" type="date" />
    		<property name="inventoryOrderETADate" column="AI_INVENTORY_ORDER_ETA" type="date" />
    		<property name="inventoryReorderPoint" column="AI_INVENTORY_REORDER_POINT" type="int" />
    		<property name="isbn" column="AI_ISBN_NUMBER" />
    		
    		<set name ="memberTypes"
    				table="MX_ACCT_ITEM_MEM_TYPE"
    				lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID"/>
    			<many-to-many class ="com.netmemex.netmx.domain.MemberType" column="MT_CODE"/>
    		</set>
    		
    		<property name="price" column="AI_PRICE"  type="float"/>
    		
    		<set name ="prices"
    				table="MX_ACCT_ITEM_PRICE"
    				lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID"/>
    			<one-to-many class ="com.netmemex.netmx.domain.transactions.AccountItemPrice"/>
    		</set>
    		
    		<property name="name" column="AI_NAME" />
    		<property name="needsInventory" column="AI_INVENTORY_IND" type="yes_no"/>
    		<property name="needsShipping" column="AI_SHIPPING_IND" type="yes_no"/>
    		<property name="needsTax" column="AI_TAX_IND" type="yes_no"/>
    						
    		<set name ="parentItems"
    				table="MX_ACCT_SUB_ITEM"
    				lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID_CHILD"/>
    			<many-to-many class ="com.netmemex.netmx.domain.transactions.AccountItem" column="AI_ID_PARENT"/>
    		</set>
    		
    		<property name="partNumber" column="AI_PART_NUMBER" />
    		<property name="period" column="AI_PERIOD_IND" type="yes_no"/>
    		
    		<many-to-one name="pkgType" class="com.netmemex.netmx.domain.lookup.AccountItemPkgType" column="LOOKUP_PKG_TYPE_CODE"/>
    		
    		<many-to-one name="pricingType" class="com.netmemex.netmx.domain.lookup.PricingType" column="LOOKUP_CODE_PRICING_TYPE"/>
    		
    		<property name="ptpMonth" column="AI_PTP_PERIOD" type="int" />
    		<property name="ptpYear" column="AI_PTP_YEAR" type="int" />
    		<property name="qtyAllocated" column="AI_INVENTORY_QA" type="int" />
    		<property name="qtyOnHand" column="AI_INVENTORY_QOH" type="int" />
    		<property name="qtyOnOrder" column="AI_INVENTORY_QOO" type="int" />
    		<property name="recievable" column="AI_RECEIVABLE_IND" type="yes_no"/>
    		<property name="shippingCost" column="AI_SHIPPING_COST" type="float" />
    		<property name="showSubItems" column="AI_DISPLAY_SUBITEM_IND" type="yes_no"/>
    		<property name="subItemOnly" column="AI_SUB_ITEM_ONLY_IND" type="yes_no"/>
    		
    		<set name ="subItems"
    				table="MX_ACCT_SUB_ITEM"
    				lazy="true"
    				cascade="save-update">
    			<key column ="AI_ID_PARENT"/>
    			<many-to-many class ="com.netmemex.netmx.domain.transactions.AccountItem" column="AI_ID_CHILD"/>
    		</set>
    		
    		<property name="termDate" column="AI_TERM_DATE" type="date" />	
    		<property name="updateDate" column="AI_UPDATE_DATE" type="date" />	
    		
    		<many-to-one name="updateUser" class="com.netmemex.netmx.domain.Master" column="AI_UPDATE_MAST_ID" />		
    		
    		<property name="vendorAddr1" column="AI_VENDOR_ADDRESS_LINE1" />
    		<property name="vendorAddr2" column="AI_VENDOR_ADDRESS_LINE2" />
    		<property name="vendorAddr3" column="AI_VENDOR_ADDRESS_LINE3" />
    		<property name="vendorCity" column="AI_VENDOR_ADDRESS_CITY" />
    		<property name="vendorCountry" column="AI_VENDOR_ADDRESS_COUNTRY" />
    		<property name="vendorEmail" column="AI_VENDOR_EMAIL" />
    		<property name="vendorFax" column="AI_VENDOR_FAX" />
    		<property name="vendorName" column="AI_VENDOR_NAME" />
    		<property name="vendorPhone" column="AI_VENDOR_PHONE" />
    		<property name="vendorState" column="AI_VENDOR_ADDRESS_STATE" />
    		<property name="vendorUrl" column="AI_VENDOR_URL" />
    		<property name="vendorZip" column="AI_VENDOR_ADDRESS_ZIP" />
    		<property name="weight" column="AI_WEIGHT" type="float" />
    		
    	</class>
    </hibernate-mapping>

  8. #8

    Default

    I'm not sure where have you gone wrong. Hmmm. I wish I could view your entire project so that at least I could try to work it out and trace your code.

    I had that problem too before. I forgot the stack trace but the problem is all about sessions.

    The scenario is like this. I can add, edit, and delete but in due time I can't do them anymore. The problem was there are sessions that aren't closed and the unclosed sessions exceeded the allowed session to be opened.

    It's a hibernate issue and I can't fix it if I can't take a look at your entire codes. I would appreciate if I you could email it to me in .zip format.

  9. #9
    Join Date
    May 2006
    Posts
    112

    Default

    Thanks for your help. I really appreciate it. Unfortunately I am not allowed to send out all of the code. Silly security measures.

    I assumed Spring's Hibernate transaction manager took care of opening and closing sessions as and when required. So whenever a new session is required it would go through the pool and close an inactive session and start a new one.

    I am sorry I am not able to understand this as to why do we have to write code to explicitly close inactive sessions so that it never runs out of allowed sessions.

    If that is the case then is this not an issue that Spring's Hibernate Transaction Manager should handle????


    Does any one have any ideas???

    ~s.

  10. #10

    Default

    Hi some one,

    I had the same assumption about Transaction Manager. But I'm not really sure where had I gone wrong. I forgot how to reproduce the error because I already fixed it and the project is already running smoothly.


    What I did is... in the database layer, I opened a session then I created an instance and copied all the values of the primitive datatypes of the object retrieved from the database. Then I closed the session. After which, I returned the instance.


    Why don't you just clean the project (remove the target folder or the folder that contains the .class files) and send it to my email below.


    Honestly, I really wanted to deal with Hibernate problems because the more you fix, the more you learn. I am dealing now with hardcore java project and I want to refresh my knowledge in java web app. After all, I owe a lot from this community because there are lots of answers here which solved my problems.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •