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

Thread: Proper method of accessing spring /hibernate via plain servlets?

  1. #1
    Join Date
    Mar 2007
    Posts
    5

    Default Proper method of accessing spring /hibernate via plain servlets?

    I have tried a few different ways to access my DB layer via servlet code - none seem to be working properly

    scenario 1
    Code:
    //Global variables
    private ServletContext servletContext;
    private XmlWebApplicationContext webAppCtx;
    
    public void init(ServletConfig servletConfig) throws ServletException
    {
    	super.init( servletConfig );
    	servletContext = servletConfig.getServletContext();
    	webAppCtx = (XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(servletContext);
    }
    
    public void destroy()
    {
    	properties = null;
    	webAppCtx.destroy();
    	webAppCtx = null;
    }
    
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException
    {
    	......
    	//do some things with the XmlWebApplicationContext - do not close/destroy or set it to null 
    	......
    
    }
    This example results in the application maxing out the connections to the DB and subsequently hanging the GUI interaction driven by the servlet. Am I missing some way to kill the connection but not re-read the bean configuration file?

    scenario 2
    Code:
    //Global variables
    private ServletContext servletContext;
    
    public void init(ServletConfig servletConfig) throws ServletException
    {
    	super.init( servletConfig );
    	servletContext = servletConfig.getServletContext();
    }
    
    public void destroy()
    {
    	properties = null;
    }
    
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException
    {
    	XmlWebApplicationContext webAppCtx = null;
    	
    	try
    	{   
    		webAppCtx = (XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(servletContext);
    		....
    		//do stuff with the context
    		....
    		webAppCtx.close();
    		webAppCtx = null;
    	
    	}catch (Exception e) {
    		.....
    	}finally {
    		try {
    			.....
    			if (webAppCtx != null) {
    				webAppCtx.close();
    				webAppCtx = null;
    			} 
    		}catch (Exception e) {
    			....
    		} finally {}
    	}
    }

    This scenario results in the following exception on bean access attempts after the first successful bean access.

    Code:
    23:24:22,253 ERROR [STDERR] java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext
    23:24:22,253 ERROR [STDERR] 	at org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory(AbstractRefreshableApplicationContext.java:120)
    23:24:22,253 ERROR [STDERR] 	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:683)

    I feel like i am close to having this work correctly, but i am just missing something.

    Any suggestions / examples ?

    Thanks....

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    What you are doing it's wrong at all. You're looking up the context, instead of creating a new one which some people do. You are doing the right thing. You don't want to destroy the context however, if you are using ContextLoaderListener this will be done for you.

  3. #3
    Join Date
    Mar 2007
    Posts
    7

    Default

    It seems the problem is more to do with the database connection pool, and how it is configured, rather than with how you are gaining access to it.

  4. #4
    Join Date
    Mar 2007
    Posts
    5

    Default Got it working - feels dirty though

    i got it to work - but the solution feels 'dirty' - dbcp is now set up to clean up the connections agressivly
    i would rather close the connections myself but i can not figure out how to do that


    controlling servlet
    Code:
    public class ActionController extends HttpServlet
    {
    	
    //Global variables
    private ServletContext servletContext;
    
    public void init(ServletConfig servletConfig) throws ServletException
    {
    	super.init( servletConfig );
    	servletContext = servletConfig.getServletContext();
    }
    
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException
    {
    	XmlWebApplicationContext webAppCtx = null;
    	
    	try
    	{   
    		webAppCtx = (XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(servletContext);
    		
    		
    		----- do stuff with the context ---
    		
    		webAppCtx = null;
    	
    	}catch (Exception e) {
    		....
    	}finally {
    		try {
    			....
    			if (webAppCtx != null) {
    				webAppCtx = null;
    			} 
    		}catch (Exception e) {
    			....
    		} finally {}
    	}
    
    }//end service method
    
    }//end ActionController class

    web.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" 
    	xmlns="http://java.sun.com/xml/ns/j2ee" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    
    	....
    
    	<listener>
       		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	
    	---- servlet declarations ----
    </web-app>

    applicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    	<bean id="mysql" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName">
    			<value>com.mysql.jdbc.Driver</value>
    		</property>
    		<property name="url">
    			<value>jdbc:mysql://localhost:3306/DBNAME</value>
    		</property>
    		<property name="username">
    			<value>USERNAME</value>
    		</property>
    		<property name="password">
    			<value>PASSWORD</value>
    		</property>
    		<property name="poolPreparedStatements">
    			<value>true</value>
    		</property>
            <property name="maxActive">
            	<value>20</value>
            </property>
            <property name="maxIdle">
            	<value>1</value>
            </property>
            <property name="maxWait">
            	<value>1000</value>
            </property>
            <property name="removeAbandoned">
            	<value>true</value>
            </property>
            <property name="removeAbandonedTimeout">
            	<value>1</value>
            </property>
            <property name="logAbandoned">
            	<value>false</value>
            </property>
    	</bean>
    	<bean id="LocalSessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource">
    			<ref bean="mysql" />
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">
    					org.hibernate.dialect.MySQLDialect
    				</prop>
    			</props>
    		</property>
    		<property name="mappingResources">
    			<list>
    				<value>XXX/Users.hbm.xml</value>
    			</list>
    		</property></bean>
    	<bean id="UsersDAO" class="XXX.UsersDAO">
    		<property name="sessionFactory">
    			<ref bean="LocalSessionFactory" />
    		</property>
    	</bean>
    </beans>
    if anyone knows how i can clean up my own DB connections i would appreciate it, but this works for now..

    thanks

  5. #5
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    What are you acutally doing with the Connection? As a previous post said, I presume they simply aren't being cleanup up correctly. It would be useful to know what you are doing with connections. Are you using them directly or let Hibernate manage them? How are you performing your transaction management?

  6. #6
    Join Date
    Mar 2007
    Posts
    5

    Default

    once i have the xmlwebapplication context - i am using it to get beans (DAO) and then from there grab the hibernate java classes that represent the DB tables (DTO) - perform some operations on the attribute data and then save it back to the db - sometimes it is just a read operation

    i suppose that hibernate is managing the connections?? not really sure - this is my first project with spring/hibernate - normally used to regular connections/resultsets and all that fun stuff - i do not believe that i am directly using them

    transactions? not really sure - i think that every db communication is being treated as its own transaction - which works for now -- although i will have to figure out how to encapsulate a few calls into one transaction in the near future

    i found that by adding hibernate.connection.release_mode = auto to the hibernateProperties section of the session factory bean is now not artifacting connections

    Code:
    <bean id="LocalSessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource">
    			<ref bean="mysql" />
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">
    					org.hibernate.dialect.MySQLDialect
    				</prop>
    				<prop key="hibernate.connection.release_mode">
    					auto
    				</prop>
    			</props>
    		</property>
    		<property name="mappingResources">
    			<list>
    				<value>XXX/Users.hbm.xml</value>
    				<value>
    				</list>
    		</property>
    	</bean>

  7. #7
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    You shouldn't really have to alter the connection release mode, I'd leave it as default which is actually auto. How are you using Hibernate? Are you using HibernateDaoSupport? Are you managing the Session yourself? It would be useful to see the code you are running.
    http://www.hibernate.org/hib_docs/v3...ection-release

  8. #8
    Join Date
    Mar 2007
    Posts
    5

    Default

    using hibernatedaosupport - not managing the session

    using it like so

    actionController - *code above* - will call a static method like this

    Code:
    public static void printValidity_DB(HttpServletRequest req, PrintWriter os, XmlWebApplicationContext webAppCtx){
    	
    	GuiFieldGroupsDAO_Custom guiGrpDAO = (GuiFieldGroupsDAO_Custom) webAppCtx.getBean("GuiFieldGroupsDAO_Custom");
    	GuiFieldDisplayDAO_Custom guiDAO = (GuiFieldDisplayDAO_Custom) webAppCtx.getBean("GuiFieldDisplayDAO_Custom");
    	
    	...
    	try{
    		....
    		ListIterator grpItr = guiGrpDAO.getGroupsInOrder().listIterator();
    		
    		while(grpItr.hasNext()){
    			
    			GuiFieldGroups guiGrp = (GuiFieldGroups)grpItr.next();
    			
    			
    			ListIterator guiItr = guiDAO.getEditDisplayedInOrderByGroup(guiGrp).listIterator();
    				
    							while(guiItr.hasNext()){
    				GuiFieldDisplay guiDisp = (GuiFieldDisplay) guiItr.next();
    				
    				//perform read only operations on the guiDisp object
    				
    				guiDisp = null;
    			}
    
    			guiItr = null;
    
    			
    			guiGrp = null;
    			
    		}
    		
    		
    		grpItr = null;
    		
    	}catch(XXXXX){
    		.....
    	}
    	
    	guiDAO = null;
    	guiGrpDAO = null;
    }

    GuiFieldDisplayDAO
    Code:
    public class GuiFieldDisplayDAO extends HibernateDaoSupport {
    
        private static final Log log = LogFactory.getLog(GuiFieldDisplayDAO.class);
    
    	//property constants
    	...............BUNCH OF CONSTANTS
    
    	protected void initDao() {
    		//do nothing
    	}
        
        public void save(GuiFieldDisplay transientInstance) {
            log.debug("saving GuiFieldDisplay instance");
            try {
                getHibernateTemplate().save(transientInstance);
                log.debug("save successful");
            } catch (RuntimeException re) {
                log.error("save failed", re);
                throw re;
            }
        }
        
    	public void delete(GuiFieldDisplay persistentInstance) {
            log.debug("deleting GuiFieldDisplay instance");
            try {
                getHibernateTemplate().delete(persistentInstance);
                log.debug("delete successful");
            } catch (RuntimeException re) {
                log.error("delete failed", re);
                throw re;
            }
        }
        
        public GuiFieldDisplay findById( java.lang.Integer id) {
            log.debug("getting GuiFieldDisplay instance with id: " + id);
            try {
                GuiFieldDisplay instance = (GuiFieldDisplay) getHibernateTemplate()
                        .get("com.lmco.tad.framework.GuiFieldDisplay", id);
                return instance;
            } catch (RuntimeException re) {
                log.error("get failed", re);
                throw re;
            }
        }
        
        
        public List findByExample(GuiFieldDisplay instance) {
            log.debug("finding GuiFieldDisplay instance by example");
            try {
                List results = getHibernateTemplate().findByExample(instance);
                log.debug("find by example successful, result size: " + results.size());
                return results;
            } catch (RuntimeException re) {
                log.error("find by example failed", re);
                throw re;
            }
        }    
        
        public List findByProperty(String propertyName, Object value) {
          log.debug("finding GuiFieldDisplay instance with property: " + propertyName
                + ", value: " + value);
          try {
             String queryString = "from GuiFieldDisplay as model where model." 
             						+ propertyName + "= ?";
    		 return getHibernateTemplate().find(queryString, value);
          } catch (RuntimeException re) {
             log.error("find by property name failed", re);
             throw re;
          }
    	}
    
    	public GuiFieldDisplay merge(GuiFieldDisplay detachedInstance) {
            log.debug("merging GuiFieldDisplay instance");
            try {
                GuiFieldDisplay result = (GuiFieldDisplay) getHibernateTemplate()
                        .merge(detachedInstance);
                log.debug("merge successful");
                return result;
            } catch (RuntimeException re) {
                log.error("merge failed", re);
                throw re;
            }
        }
    
        public void attachDirty(GuiFieldDisplay instance) {
            log.debug("attaching dirty GuiFieldDisplay instance");
            try {
                getHibernateTemplate().saveOrUpdate(instance);
                log.debug("attach successful");
            } catch (RuntimeException re) {
                log.error("attach failed", re);
                throw re;
            }
        }
        
        public void attachClean(GuiFieldDisplay instance) {
            log.debug("attaching clean GuiFieldDisplay instance");
            try {
                getHibernateTemplate().lock(instance, LockMode.NONE);
                log.debug("attach successful");
            } catch (RuntimeException re) {
                log.error("attach failed", re);
                throw re;
            }
        }
    
    	public static GuiFieldDisplayDAO getFromApplicationContext(ApplicationContext ctx) {
        	return (GuiFieldDisplayDAO) ctx.getBean("GuiFieldDisplayDAO");
    	}
    }


    GuiFieldDisplayDAO_Custom

    Code:
    public class GuiFieldDisplayDAO_Custom extends GuiFieldDisplayDAO {
    
       
        
        public List getEditDisplayedInOrderByGroup(GuiFieldGroups guiGroup) {
    	    Criteria crit = null;
    	      
    	      try {
    	        
    	    	  crit = getSession().createCriteria(GuiFieldDisplay.class);
    	    	  crit.add(Expression.eq("guiFieldGroups", guiGroup ));
    	    	  crit.add(Expression.eq("XXXXX", 1 ));
    	    	  crit.addOrder(Order.asc("XXXXX"));
    	    	  
    	    	  return crit.list();
    	      } catch (RuntimeException re) {
    	        throw re;
    	      }finally{
    	    	  crit = null;
    	      }
    		}
    	
    	
    }

    GuiFieldDisplay
    Code:
    public class GuiFieldDisplay  implements java.io.Serializable {
    
    
        // Fields    
    
         private Integer fieldId;
         private GuiFieldGroups guiFieldGroups;
         .....
    	//OTHER fields
    	......
    
    
        // Constructors
    
        /** default constructor */
        public GuiFieldDisplay() {
        }
    
    	  
        // Property accessors
    
        public Integer getFieldId() {
            return this.fieldId;
        }
        
        public void setFieldId(Integer fieldId) {
            this.fieldId = fieldId;
        }
    
        .....
    	//OTHER GETTERS AND SETTERS
    	......
    }

  9. #9
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    You are calling getSession() but you're not closing the Session. As you aren't using transactions I guess this could be the problem.
    Code:
    crit = getSession().createCriteria(GuiFieldDisplay.class);
    If you change the code to use the HibernateTemplate instead that would fix it I think.
    Code:
    getHibernateTemplate().execute(new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            Criteria crit = session.createCriteria(GuiFieldDisplay.class);
            // do the rest of the work
        }
    });

  10. #10
    Join Date
    Mar 2007
    Posts
    5

    Default It Works!

    Thanks for your help - changing how i deal with criteria has solved the last of my problems

    I changed the connection pooling settings to be a little less aggressive and now the application is running fine

Posting Permissions

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