this project using spring springMVC hibernate
how could I use "org.springframework.orm.hibernate4.support.OpenSessionInViewFilter"
to stove the lazy load
problem "could not initialize proxy - no Session"
in CommonDao if I set Session session = super.currentSession()
the lazy load cause the Exception "could not initialize proxy - no Session".
if I use Session session = super.getSessionFactory().openSession()
, it won't cause the exception, BUT...after about 30 times request from the browser it can't get any datas.it seems that the sessionFactory have no more session to use(it seems OpenSessionInViewFilter
didn't close any session for each request), but i'm sure that I already config "OpenSessionInViewFilter"
in my web.xml
problem summary:
super.currentSession()
or super.getSessionFactory().openSession()
? here is my code
DAO:
@Repository("commonDao")
public class CommonDao<T> extends HibernateDaoSupport {
@Resource
public void setSessionFacotry(SessionFactory sessionFacotry) {
super.setSessionFactory(sessionFacotry);
}
@SuppressWarnings("unchecked")
public T LoadEntityById(Class<T> clazz, Object id, String idName) {
Session session = super.currentSession();// HERE!!!
//if I use super.getSessionFactory().openSession() , it won't cause the exception, BUT...after about 30 times request from the browser it can't get any datas
Criteria cri = session.createCriteria(clazz);
if (null == idName || idName.length() <= 0) {
idName = getClass().getName() + "Id";
}
cri.add(Restrictions.eq(idName, id));
List<T> result = cri.list();
if (null != result && result.size() > 0) {
return (T) cri.list().get(0);
}
return null;
}
}
MealMenuDao use commondao.LoadEntityById() method
public class MealMenuDaoImpl implements MealMenuDao {
@Autowired
private CommonDao<MealMenu> commonDao;
@Autowired
private SessionFactory sessionFactory;
@Override
public MealMenu FindEnityById(Long Id) {
return commonDao.LoadEntityById(MealMenu.class, Id, "mealMenuId");
}
}
SERVICE:
@Service("mealMenuService")
@Transactional
public class MealMenuServiceImpl implements MealMenuService {
@Autowired
private MealMenuDao mealMenuDao;
@Override
public MealMenu getMealMenuById(Long id) {
return mealMenuDao.FindEnityById(id);
}
PO:
@Entity
@Component
public class MealMenu extends BaseDomain {
private Long mealMenuId;
private String menuName;
private int menuType;
private int canteenId;
private int state;
private Date createTime;
private Date editTime;
private String description;
private Set<MealPackage> mealPackages;
private Canteen canteen;
@Id
// @GeneratedValue(generator = "system-uuid")
// @GenericGenerator(name = "system-uuid", strategy = "uuid")
@GeneratedValue
@Column(name = "ID", unique = true, nullable = false)
public Long getMealMenuId() {
return mealMenuId;
}
public void setMealMenuId(Long mealMenuId) {
this.mealMenuId = mealMenuId;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public int getMenuType() {
return menuType;
}
public void setMenuType(int menuType) {
this.menuType = menuType;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public int getCanteenId() {
return canteenId;
}
public void setCanteenId(int canteenId) {
this.canteenId = canteenId;
}
@Column(updatable = false)
@Temporal(TemporalType.TIMESTAMP)
@JsonSerialize(using = CustomDatetimeSerializer.class)
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@JsonSerialize(using = CustomDatetimeSerializer.class)
public Date getEditTime() {
return editTime;
}
public void setEditTime(Date editTime) {
this.editTime = editTime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@JsonIgnore
@ManyToMany(targetEntity = MealPackage.class, fetch = FetchType.LAZY)
@JoinTable(name = "R_MealPackage_MealMenu", joinColumns = @JoinColumn(name = "MealMenu_ID"), inverseJoinColumns = @JoinColumn(name = "MealPackage_ID"))
public Set<MealPackage> getMealPackages() {
return mealPackages;
}
public void setMealPackages(Set<MealPackage> mealPackages) {
this.mealPackages = mealPackages;
}
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "CanteenID")
public Canteen getCanteen() {
return canteen;
}
public void setCanteen(Canteen canteen) {
this.canteen = canteen;
}
}
CONTROLLER:
@Controller
@RequestMapping("/admin/mealMenuManage")
public class SysAdmin_MealMenuController {
@RequestMapping("/test")
@ResponseBody
public Object test(HttpServletRequest request, Long id) {
MealMenu mealMenu = this.mealMenuService.getMealMenuById(id);
Set<MealPackage> mp = mealMenu.getMealPackages();
mp.size();
return mp;
}
}
WEB.XML I use OpenSessionInViewFilter but it dosen't work
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,classpath:spring-hibernate.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springMVC config -->
<servlet>
<description>spring mvc servlet</description>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>spring mvc config file</description>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
,classpath:spring-*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>userplatform/index.html</welcome-file>
</welcome-file-list>
<!-- openSessionInView config -->
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<context:property-placeholder location="classpath:database.properties" />
<context:component-scan base-package="com.flowingsun.webapp">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>
Spring-hibernate.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- MySQL5 -->
<property name="driverClass" value="${driverClassName}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="maxPoolSize" value="40"></property>
<property name="minPoolSize" value="1"></property>
<property name="initialPoolSize" value="1"></property>
<property name="maxIdleTime" value="20"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.flowingsun.webapp.domain</value>
</list>
</property>
</bean>
<bean name="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
</beans>
When i use this url:
http://localhost:8080/CommonOrderMealWepApp_Maven/admin/mealMenuManage/test.html?id=1 it report the exception
Exception stack:
HTTP Status 500 - Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.flowingsun.webapp.domain.MealMenu.mealPackages, could not initialize proxy - no Session
type Exception report
message Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.flowingsun.webapp.domain.MealMenu.mealPackages, could not initialize proxy - no Session
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.flowingsun.webapp.domain.MealMenu.mealPackages, could not initialize proxy - no Session
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.flowingsun.webapp.domain.MealMenu.mealPackages, could not initialize proxy - no Session
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:572)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:153)
org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160)
com.flowingsun.webapp.controller.SysAdmin_MealMenuController.test(SysAdmin_MealMenuController.java:106)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:178)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:444)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:432)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.32 logs.
Apache Tomcat/8.0.32
thanks for your help
Relative to your first problem. in CommonDao if it set session = super.currentSession() the lazy load cause the Exception "could not initialize proxy - no Session".
If you take a look on your stack trace:
failed to lazily initialize a collection of role:
com.flowingsun.webapp.domain.MealMenu.mealPackages, could not initialize
proxy - no Session
This commonly happens when you get your objects and you have some list that are not joined by fetch in query. So information is not retrieved from database. Try to modify your criteria adding left join.
Then:
Set<MealPackage> mp = mealMenu.getMealPackages();
When you access getMealPackages(); it returns your exception.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.