samedi 4 avril 2015

LazyInitializationException: failed to lazily initialize a collection of role (Help required in ManyToMany mapping)


Vote count:

0




I'm fairly newbie to Spring-hibernate. I'm trying to create a simple Note-Taking application. DB Structure:



CREATE TABLE `category` (
`id` mediumint(9) NOT NULL,
`category` varchar(100) NOT NULL,
`details` varchar(200) NOT NULL,
`parentid` mediumint(9) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `category`
ADD PRIMARY KEY (`id`);

CREATE TABLE `notes` (
`id` mediumint(9) NOT NULL,
`heading` varchar(200) NOT NULL,
`notes` mediumtext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `notes`
ADD PRIMARY KEY (`id`);

CREATE TABLE IF NOT EXISTS `category_notes` (
`category_id` mediumint(9) NOT NULL,
`notes_id` mediumint(9) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `category_notes`
ADD PRIMARY KEY (`category_id`,`notes_id`), ADD KEY `notes_id` (`notes_id`);

ALTER TABLE `category_notes`
ADD CONSTRAINT `category_notes_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `category_notes_ibfk_2` FOREIGN KEY (`notes_id`) REFERENCES `notes` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;


Web.xml:



<display-name>DNotes</display-name>

<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Filters -->
<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>



<!-- Processes application requests -->
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/app-servlet.xml,
/WEB-INF/spring-security.xml
</param-value>

</context-param>


app-servlet.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://ift.tt/GArMu6"
xmlns:xsi="http://ift.tt/ra1lAU" xmlns:context="http://ift.tt/GArMu7"
xmlns:util="http://ift.tt/OGfeTW" xmlns:mvc="http://ift.tt/1bHqwjR"
xmlns:p="http://ift.tt/1jdM0fE"
xmlns:tx="http://ift.tt/OGfeU2"
xsi:schemaLocation="http://ift.tt/1bHqwjR http://ift.tt/JWpJWM
http://ift.tt/GArMu6 http://ift.tt/1jdM0fG
http://ift.tt/OGfeTW http://ift.tt/1aj0W5e
http://ift.tt/GArMu7 http://ift.tt/1bGeTcI
http://ift.tt/OGfeU2 http://ift.tt/OGffan">

<context:component-scan base-package="com.app.notes" />
<context:property-placeholder location="classpath:database.properties" />
<mvc:resources mapping="/resources/**" location="/resources/" />

<mvc:annotation-driven />

<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="classpath:messages_en"/>

<!-- <bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:Messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean> -->

<!-- Hibernate Configuration -->

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.app.dnotes.models.login.Users</value>
<value>com.app.dnotes.models.login.UserRole</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan" value="com.app.notes"></property>
</bean>

<!-- Hibernate Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />


<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<!-- Internal View Resolver.. -->

<!-- <bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean> -->

<!-- Tiles configuration -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"/>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<value>/WEB-INF/layouts/views.xml</value>
</list>
</property>
</bean>

</beans>


Category.java



@Entity
@Table(name="category")
public class Category {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@NotNull
@Size(min=1,max=100) //jsr Validation
@Column private String category;

@Size(min=0,max=200)
@Column private String details;

@Column private int parentid;

@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinTable(name = "category_notes", joinColumns = { @JoinColumn(name = "category_id") }, inverseJoinColumns = { @JoinColumn(name = "notes_id") })
private Set<Notes> notes = new HashSet<Notes>();

public Category() {
super();
// TODO Auto-generated constructor stub
}

public Category(int id, String category, String details, int parentid) {
super();
this.id = id;
this.category = category;
this.details = details;
this.parentid = parentid;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getCategory() {
return category;
}

public void setCategory(String category) {
this.category = category;
}

public String getDetails() {
return details;
}

public void setDetails(String details) {
this.details = details;
}

public int getParentid() {
return parentid;
}

public void setParentid(int parentid) {
this.parentid = parentid;
}

public Set<Notes> getNotes() {
return notes;
}

public void setNotes(Set<Notes> notes) {
this.notes = notes;
}

@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}

}


Notes.java



@Entity
@Table(name="notes")
public class Notes {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@NotNull
@Size(min=1,max=200) //jsr Validation
@Column private String heading;

@Column private String notes;

@ManyToMany(mappedBy = "notes")
private Set<Category> categories = new HashSet<Category>();

public Notes() {
super();
// TODO Auto-generated constructor stub
}

public Notes(int id, String heading, String notes) {
super();
this.id = id;
this.heading = heading;
this.notes = notes;
}

public Notes(int id, String heading, String notes, Set<Category> categories) {
super();
this.id = id;
this.heading = heading;
this.notes = notes;
this.categories=categories;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getHeading() {
return heading;
}

public void setHeading(String heading) {
this.heading = heading;
}

public String getNotes() {
return notes;
}

public void setNotes(String notes) {
this.notes = notes;
}

public Set<Category> getCategories() {
return categories;
}

public void setCategories(Set<Category> categories) {
this.categories = categories;
}

@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}


}


UserController.java



@RequestMapping(value="/user/viewAllCategories", method=RequestMethod.GET)
public String getAllCategories(Model model)
{
if (!model.containsAttribute("categoryForm")) {
model.addAttribute("categoryForm", new Category());
}

if (!model.containsAttribute("SEARCH_CATEGORY_RESULTS_KEY")) {
List<Category> categories = usersService.getCategories();
model.addAttribute("SEARCH_CATEGORY_RESULTS_KEY", categories);
}

List<Category> categories = usersService.getCategoriesAndNotes();
categories.add(0, new Category());
model.addAttribute("categories", categories);


return "user/viewAllCategories";
}


viewAllCategories.jsp



<form:form action="saveCategory" method="post" role="form" commandName="categoryForm">
<form:hidden path="id" />
<div class="form-group">
<spring:message code="categoryPage.categoryNewPlaceHolder"
var="categoryNewPlaceHolder" />
<form:input path="category" class="form-control"
placeholder="${categoryNewPlaceHolder }" />
<p class="text-danger"><form:errors path='category' /></p>
</div>
<div class="form-group">
<spring:message code="categoryPage.categoryDetailsPlaceHolder"
var="categoryDetailsPlaceHolder" />
<form:input path="details" class="form-control"
placeholder="${categoryDetailsPlaceHolder }" />
<p class="text-danger"><form:errors path='details' /></p>
</div>
<div class="form-group">
<label>Parent****</label>
<form:select path="parentid" class="form-control">
<form:options items="${categories}" itemLabel="category"
itemValue="id"></form:options>
</form:select>
<p class="help-block">
<form:errors path="parentid" cssStyle="color:red"></form:errors>
</p>
</div>
<button type="submit" class="btn btn-default"><spring:message code="common.submit" /></button>
</form:form>


Its giving the following error:



org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.notes.models.Categories.notes, could not initialize proxy - no Session


I tried to overcome lazy initialization as below:



@SuppressWarnings("unchecked")
public List<Category> getCategoriesAndNotes() {
// Returns section..
List<Category> categories = getSession().createQuery("from " + Category.class).list();
for(Category category:categories)
Hibernate.initialize(category.getNotes());
return categories;
}


Please advise a solution...


Any help is highly appreciated.... I'm using Tiles to render view.. I tried FetchType.EAGER in class as well. not able to get a solution...



asked 1 min ago







LazyInitializationException: failed to lazily initialize a collection of role (Help required in ManyToMany mapping)

Aucun commentaire:

Enregistrer un commentaire