-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Transaction problem - two open sessions
PostPosted: Tue Jun 30, 2009 2:50 pm 
Beginner
Beginner

Joined: Fri Mar 21, 2008 8:07 pm
Posts: 23
I'm getting the following error:

Code:
Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'populator' defined in class path resource [spring-core.xml]: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Initialization of DAO failed; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions


I thinking that I'm not using spring transactions properly, but am not sure how to solve it. The problem occurs at the following line in BootstrapDataPopulator.java:
getSession().save(m);

Any help would be appreciated!

Here's the code:

## Spring-hibernate config
Code:
    <!-- Enable annotation configuration -->
    <context:annotation-config/>

    <!-- Scan packages for Spring annotations -->
    <context:component-scan base-package="myapp.service"/>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <!-- ommitted -->
    </bean>

    <!-- Transaction support beans -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- Spring AOP auto-proxy creation (required to support Shiro annotations) -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

    <!-- Populates the database with default data. -->
    <bean id="populator" class="myapp.service.BootstrapDataPopulator">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- Post processor that automatically invokes init() and destroy() methods -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>


## myapp.service.BootstrapDataPopulator.java

Code:
@Transactional
public class BootstrapDataPopulator extends HibernateDaoSupport {
   
    private static final Logger log = LoggerFactory.getLogger(BootstrapDataPopulator.class);

    public void initDao() throws Exception {
      buildRolesData();
      buildMemberData();
    }
   
    private static final String[][] ROLES = {
      {"member"},
      {"manager"},
      {"admin"}
    };

    private void buildRolesData() {
       log.debug("Building Roles Data");
   for (int i = 0; i < ROLES.length; i++) {
      Role r = new Role(ROLES[i][0]);
           getSession().save(r);
   }
    }

    private static final String[][] MEMBERS = {
      {"tom","Tom","Smith"},
      {"member","Sue","Stark"},
      {"admin","Mark","Brisk"}
    };

    private static final String[][] MEMBER_ROLES = {
      {
         "member","manager"
      },
      {
         "member"
      },
      {
         "member","manager","admin"
      }
    };

    private void buildMemberData() {
       log.debug("Building Member Data");
   for (int i = 0; i < MEMBERS.length; i++) {
      Member m= new Member();
      m.setUsername(MEMBERS[i][0]);
      m.setPassword(MEMBERS[i][0]);

      for (int j = 0; j < MEMBER_ROLES[i].length; j++) {
              Role r = (Role) getSession().createCriteria(Role.class)
            .add(Restrictions.eq("name", MEMBER_ROLES[i][j]))
            .uniqueResult();
         if (r != null) {
            m.addRole(r);
         }
      }
           getSession().save(m);
   }
    }
}


## myapp.model.Member.java
Code:
@Entity
@Table(name="members")
@Cache(usage= CacheConcurrencyStrategy.READ_WRITE)
public class Member extends AbstractEntity {
    private static final long serialVersionUID = 1L;

    private String username;
    private String password;
    private Set<Role> roles = new HashSet<Role>();
   
   public Member() {
      super();
   }

    @Basic(optional=false)
    @Column(length=100)
    @Index(name="idx_members_username")
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    @Basic(optional=false)
    @Column(length=255)
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

   @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="members_roles")
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
   public Set<Role> getRoles() {
      return this.roles;
   }
   public void setRoles(Set<Role> roles) {
      this.roles = roles;
   }
   public Role hasRole(Role role) {
      if (this.roles.contains(role)) {
         return role;
      }
      return null;
   }
   public boolean addRole(Role role) {
      return this.roles.add(role);
   }
   public boolean removeRole(Role role) {
      return this.roles.remove(role);
   }

}


## myapp.model.Role.java
Code:
@Entity
@Table(name="roles")
@Cache(usage= CacheConcurrencyStrategy.READ_WRITE)
public class Role implements Serializable {
   private static final long serialVersionUID = 1L;

    private Long id;
    private String name;

    protected Role() {
    }
    public Role(String name) {
        this.name = name;
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Basic(optional=false)
    @Column(length=100)
    @Index(name="idx_roles_name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


Top
 Profile  
 
 Post subject: Re: Transaction problem - two open sessions
PostPosted: Tue Jun 30, 2009 3:49 pm 
Beginner
Beginner

Joined: Fri Mar 21, 2008 8:07 pm
Posts: 23
Sorry for the posting -- I was doing something stupid. I've been messing around with Spring transaction management and thought the problem was related. Instead, I was simply calling getSession() everytime I did something instead of calling it once, and then reusing that session. So I did this:

Session sess = getSession();

And then I used "sess" wherever I currently am using getSession().

Duh...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.