Announcement Announcement Module
Collapse
No announcement yet.
Lazy init exception with HibernateInterceptor - @ManyToMany Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lazy init exception with HibernateInterceptor - @ManyToMany

    Hi,

    I'm trying to do simple app with @ManyToMany and I have a problem with Lazy init exception. I thought that HibernateInterceptor will help but maybe I don't know how to use it.

    I hope that you will help me with solving this problem.

    This is application:

    Code:
    @Entity
    @Table(name = "role")
    public class GrantedAuthority implements Serializable{
    
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	private Serializable id;
    
    	private String name;
    	
    	private String description;
    	
    	private boolean enabled;
    	
    	@ManyToMany
    	@JoinTable(name = "user_role",    
    			   joinColumns = { @JoinColumn(name = "roleid")},  
    	           inverseJoinColumns={@JoinColumn(name="userid")})
    	@IndexColumn(name = "user")
    	private User[] users;
    	
    	@ManyToMany
    	@JoinTable(name = "role_resource",    
    			   joinColumns = { @JoinColumn(name = "roleid")},  
    	           inverseJoinColumns={@JoinColumn(name="resourceid")})
    	@IndexColumn(name = "resource")
    	private Resource[] resources;
    	
    	public Serializable getId() {
    		return id;
    	}
    
    	public void setId(Serializable id) {
    		this.id = id;
    	}
    	
    	public void setName(String name){
    		this.name = name;
    	}
    	
    	public String getName(){
    		return name;
    	}
    	
    	public String getAuthority() {
    		return name;
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	public boolean isEnabled() {
    		return enabled;
    	}
    
    	public void setEnabled(boolean enabled) {
    		this.enabled = enabled;
    	}
    	
    	public User[] getUsers() {
    		return users;
    	}
    
    	public void setUsers(User[] users) {
    		this.users = users;
    	}
    	
    	public Resource[] getResources() {
    		return resources;
    	}
    
    	public void setResources(Resource[] resources) {
    		this.resources = resources;
    	}	
    }
    Code:
    @Entity
    @Table(name = "resource")
    public class Resource implements Serializable {
    
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	private Serializable id;
    	
    	private String name;
    	
    	private String description;
    	
    	private boolean enabled;
    	
    	@ManyToMany
    	@JoinTable(name = "role_resource",    
    			   joinColumns = { @JoinColumn(name = "resourceid")},  
    	           inverseJoinColumns={@JoinColumn(name="roleid")})
    	@IndexColumn(name = "role")
    	private GrantedAuthority[] roles;
    	
    	public Serializable getId() {
    		return id;
    	}
    
    	public void setId(Serializable id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name){
    		this.name = name;
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	public boolean isEnabled() {
    		return enabled;
    	}
    
    	public void setEnabled(boolean enabled) {
    		this.enabled = enabled;
    	}
    	
    	public GrantedAuthority[] getAuthorities() {
    		return roles;
    	}
    
    	public void setAuthorities(GrantedAuthority[] roles) {
    		this.roles = roles;
    	}
    
    }
    Code:
    @Entity
    @Table(name = "user")
    public class User implements Serializable{
    
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	private Serializable id;
    	
    	private String username;
    	
    	private String password;
    	
    	private boolean accountNonExpired;
    	
    	private boolean accountNonLocked;
    	
    	private boolean credentialsNonExpired;
    	
    	private boolean enabled;
    	
    	@ManyToMany
    	@JoinTable(name = "user_role",    
    			   joinColumns = { @JoinColumn(name = "userid")},  
    	           inverseJoinColumns={@JoinColumn(name="roleid")})
    	@IndexColumn(name = "role")
    	private GrantedAuthority[] roles;
    
    
    	public Serializable getId() {
    		return id;
    	}
    	
    	public void setId(Serializable id) {
    		this.id = id;
    	}
    	
    	public String getUsername() {
    		return username;
    	}
    	
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	
    	public String getPassword() {
    		return password;
    	}
    	
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	
    	public boolean isAccountNonExpired() {
    		return accountNonExpired;
    	}
    	
    	public void setAccountNonExpired(boolean accountNonExpired) {
    		this.accountNonExpired = accountNonExpired;
    	}
    	
    	public boolean isAccountNonLocked() {
    		return accountNonLocked;
    	}
    	
    	public void setAccountNonLocked(boolean accountNonLocked) {
    		this.accountNonLocked = accountNonLocked;
    	}
    	
    	public boolean isCredentialsNonExpired() {
    		return credentialsNonExpired;
    	}
    	
    	public void setCredentialsNonExpired(boolean credentialsNonExpired) {
    		this.credentialsNonExpired = credentialsNonExpired;
    	}
    	
    	public boolean isEnabled() {
    		return enabled;
    	}
    	
    	public void setEnabled(boolean enabled) {
    		this.enabled = enabled;
    	}
    	
    	public GrantedAuthority[] getRoles() {
    		return roles;
    	}
    	
    	public void setRoles(GrantedAuthority[] roles) {
    		this.roles = roles;
    	}
    	
    	public GrantedAuthority[] getAuthorities() {
    		return  roles;
    	}
    	
    }
    Code:
    public class ACLDAOHibernateImpl extends HibernateDaoSupport implements ACLDAO {
    
    	public Collection<GrantedAuthority> getAuthority() {
    		return getHibernateTemplate().loadAll(GrantedAuthority.class);
    	}
    
    	public GrantedAuthority getAuthorityById(Integer id) {
    		GrantedAuthority authority = (GrantedAuthority) getHibernateTemplate().load(GrantedAuthority.class, id);
    	    return authority;
    	}
    
    	public Collection<Resource> getResources() {
    		return getHibernateTemplate().loadAll(Resource.class);
    	}
    
    	public Resource getResourceById(Integer id) {
    		Resource resource = (Resource) getHibernateTemplate().load(Resource.class, id);
    	    return resource;
    	}
    
    	public User getUserById(Integer id) {
    		User user = (User) getHibernateTemplate().load(User.class, id);
    	    return user;
    	}
    
    	public Collection<User> getUsers() {
    		return getHibernateTemplate().loadAll(User.class);
    	}
    
    	public GrantedAuthority saveAuthority(GrantedAuthority authority) {
    		getHibernateTemplate().saveOrUpdate(authority);
    	    return authority;
    	}
    
    	public Resource saveResource(Resource resource) {
    		getHibernateTemplate().saveOrUpdate(resource);
    	    return resource;
    	}
    
    	public User saveUser(User user) {
    		getHibernateTemplate().saveOrUpdate(user);
    	    return user;
    	}
    
    	public Collection<GrantedAuthority> searchAuthorityByName(String name) {
    		return getHibernateTemplate().findByNamedQuery("role.name", name);
    	}
    
    	public Collection<User> searchUserByName(String name) {
    		return getHibernateTemplate().findByNamedQuery("user.username", name);
    	}
    
    	public Collection<GrantedAuthority> getAuthorities() {
    		return getHibernateTemplate().loadAll(GrantedAuthority.class);
    	}
    
    	public Collection<Resource> searchResourceByName(String name) {
    		return getHibernateTemplate().findByNamedQuery("resource.name", name);
    	}
    
    }
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    	
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
    		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    	    <property name="url" value="jdbc:mysql://localhost/wat_useraccounts"/>
    	    <property name="username" value="root"/>
    	    <property name="password" value=""/>
    	</bean>
    	
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        	<property name="hibernateProperties">
         		<props>
         			<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
          		</props>
    		</property>
    		<property name="annotatedClasses">
    			<list>
    				<value>domain.User</value>
    				<value>domain.Resource</value>
    				<value>domain.GrantedAuthority</value>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor" autowire="byName" />
    	
    	<bean id="aclDaoTarget" class="dao.hibernate.ACLDAOHibernateImpl" autowire="byName"/>
    	
    	<bean id="aclDao" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces" value="dao.ACLDAO"/>
        <property name="interceptorNames">
          <list>
            <value>hibernateInterceptor</value>
            <value>aclDaoTarget</value>
          </list>
        </property>
      </bean>
    	
    	
    </beans>
    Code:
    public class Db {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml", Db.class);
    		ACLDAO aclDao = (ACLDAO) applicationContext.getBean("aclDao");
    		
    		User user = aclDao.getUserById(1);
    		System.out.println(user.getUsername());
    	}
    
    }
    Error:

    Code:
    2009-09-03 19:01:04 org.hibernate.LazyInitializationException <init>
    SEVERE: could not initialize proxy - no Session
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    	at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    	at domain.User$$EnhancerByCGLIB$$98847d7d.getUsername(<generated>)
    	at db.Db.main(Db.java:19)
    Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    	at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    	at domain.User$$EnhancerByCGLIB$$98847d7d.getUsername(<generated>)
    	at db.Db.main(Db.java:19)

  • #2
    The hibernate interceptor leaves the session open for the whole method call after it has ended the session is closed. For your case it is clased after the call to the dao method.

    Comment


    • #3
      Ok but problem is that session is not initialized ( not closed ). I think I spoiled somethink in app context. Can somebody look at it ?

      Comment


      • #4
        The problem is just and exactly that... The session which originally was used to retrieve the object and its related/lazy objects doesn't exist anymore. No configuration can help you with that, but feel free to try .

        Comment


        • #5
          Ok then how can I fix this ? I've changed fetch type in @ManyToMany to EAGER but it did not help.

          Comment


          • #6
            It depends on what you want. Do you want lazy loading?

            1) Initialize/load the full collection before the session closes
            2) Use a OpenSessionInViewFilter/*Interceptor, in your test class yuou can mimick this by opening a session before calling the dao

            If not, change your configuration to not lazy load.

            Comment

            Working...
            X