Despite using configuration below I got lazy initialize error:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: beans.Restaurant.tags, no session or session was closed
and here the
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>RestFinderWebApp</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<!-- <welcome-file>index.html</welcome-file> -->
</welcome-file-list>
<!-- Spring security: -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-security.xml,
/WEB-INF/spring-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-servlet.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="false" />
<property name="assembler">
<bean id="jmxAssembler"
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource">
<bean
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
</property>
</bean>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages" />
<bean id="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPersistence" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
(...)
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
(...)
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="myUserDAO" class="dao.UserDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="myRestaurantDAO" class="dao.RestaurantDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean name="/mojekonto.htm" class="web.HomeUserController">
<property name="userDAO" ref="myUserDAO" />
<property name="restaurantDAO" ref="myRestaurantDAO" />
<property name="loggedUser" ref="LoggedUser" />
</bean>
</beans>
my controller:
public class HomeUserController extends MultiActionController {
private UserDAO userDAO;
private TagDAO tagDAO;
public void setTagDAO(TagDAO tagDAO) {
this.tagDAO = tagDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
private LoggedUser loggedUser;
public void setLoggedUser(LoggedUser loggedUser) {
this.loggedUser = loggedUser;
}
private RestaurantDAO restaurantDAO;
public void setRestaurantDAO(RestaurantDAO restaurantDAO) {
this.restaurantDAO = restaurantDAO;
}
private FollowDAO followDAO;
public void setFollowDAO(FollowDAO followDAO) {
this.followDAO = followDAO;
}
private CommentDAO commentDAO;
public void setCommentDAO(CommentDAO commentDAO) {
this.commentDAO = commentDAO;
}
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
super.initBinder(request, binder);
binder.registerCustomEditor(List.class, "tags",new CustomCollectionEditor(List.class){
@Override
protected Object convertElement(Object element) {
Tag tag = new Tag();
if (element != null) {
int id = Integer.valueOf(element.toString());
tag.setId(id);
}
return tag;
}
});
}
public ModelAndView mojekonto(HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = loggedUser.getLoggedUser();
ModelMap modelMap = new ModelMap();
Restaurant restaurant = new Restaurant();
Restaurant userRestaurant = new Restaurant();
userRestaurant = restaurantDAO.findRestaurantByUser(user.getUsername());
modelMap.addAttribute("user", user);
modelMap.addAttribute("restaurant", restaurant);
modelMap.addAttribute("userRestaurant", userRestaurant);
return new ModelAndView("mojekonto", modelMap);
}
My class – restaurant:
@Entity
@Table(name="restaurants")
public class Restaurant {
@Id
@GeneratedValue
private int id;
private String name;
private String street;
private String city;
private String country;
private String postal_code;
private String telephone;
private String logo;
private String image;
private String description;
private float longitude;
private float latitude;
private Date last_update;
@ManyToMany //it works fine...
@JoinTable(name="user_restaurant_owner",
joinColumns={@JoinColumn(name="restaurant_id")},
inverseJoinColumns={@JoinColumn(name="username")})
private List<User> owner;
@ManyToMany //but that doesn't...
@JoinTable(name="restaurant_tag",
joinColumns={@JoinColumn(name="restaurant_id")},
inverseJoinColumns={@JoinColumn(name="tag_id")})
private List<Tag> tags;
//getters and setters:
my view jsp:
<c:forEach items="${userRestaurant.tags}" var="current">
do something
</c:forEach>
I got error when it is in “{userRestaurant.tags}”
Your config looks correct with the SpringOpenEntityManagerInViewFilter so you SHOULDN’T have to resort to eager fetching or having to pre-traverse the collection in your controller. I have a very similar configuration and pattern in an app I’m working on, and it’s working without problems. One thing you could try is to add a blank context location to your DispatcherServlet configuration. Haven’t checked, but I think it has some default behaviour to load context according to global config otherwise. This will cause the dispatcher servlet to, in effect, load a separate context rather than just creating a blank one, inheriting from the one created by the ContextLoaderListener (which is what you want it to do).
So, to your
<servlet>declaration of the DispatcherServlet, add:Update: Using the hibernate transaction manager looks a bit odd as well (considering you are using a JPA entity manager). Try changing that to use the Jpa Transaction manager instead.
Update 2: Looking over your config again, it looks like you are using a weird mix of JPA and Hibernate. For instance, you are definig two transaction managers. Why? Also, you are using the
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter(which is JPA/EntityManager), while at the same time using theorg.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor(which is Hibernate/Session). How are you looking up your entities in your DAO? Using the hibernate session or the JPA EntityManager? It might be better to stick with either JPA or Hibernate to minimize collisions.I’ve also had trouble getting the
Open*InViewInteceptor‘s to work. The filters seem more stable (you haveorg.springframework.orm.hibernate3.support.OpenSessionInViewFilter, for instance if you decide on hibernate pure).