title: Hibernate 4 lazy loading doesn't work
body: <p>I am working on a web application using spring 3 and hibernate 4. 
  I am having trouble lazy-loading a set of granted permissions of a group to which a user belongs.
  When a user object is retrieved from the database, its Group object doesn't have any permissions even though user.getGroup().getPermissions() is invoked explicitly.</p>
  
  <p>I noticed that in debug mode, if I mouse-over the User object and then navigate to the Group object inside the User object, and then navigate to its permissions, I can see its type is shown as PersistentSet, and expanding it will load permissions properly. But in non-debug mode, permissions are never lazy-loaded. What am I missing here? Thanks in advance.</p>
  
  <p>Here are the relationships among the entities:
  Users have an one-to-many relationship with groups, and groups have a many-to-many relationship with permissions.</p>
  
  <p>Here's the definition of the UserDaoImpl class </p>
  
  <pre><code>@Repository
  @Transactional
  public class UserDaoImpl implements UserDao  {
  
      @Autowired
      private SessionFactory sessionFactory;
  
      private Session getSession() {
          return sessionFactory.getCurrentSession();
      }
  
      @Override
      public User get(String username) {
          Session session = getSession();
          User user = (User) session.createCriteria(User.class).add(Restrictions.eq("username", username)).uniqueResult();
  
          Group g = user.getGroup();
  
          // calling g.getGrantedPermissions() doesn't load any permission
          Set&lt;Permission&gt; permissions = g.getGrantedPermissions();
          return user;
      }
  }
  </code></pre>
  
  <p>Here's the definition of the Permission class</p>
  
  <pre><code>@Entity
  public class Permission {
      @Id
      @GeneratedValue
      private Long id;
  
      @Column
      private String name;
  
      @Column
      private String description;
  
      public Permission()
      {
  
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getDescription() {
          return description;
      }
  
      public void setDescription(String description) {
          this.description = description;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  }
  </code></pre>
  
  <p>Here's the definition of the Group class</p>
  
  <pre><code>@Entity
  @Table(name="\"Group\"")
  public class Group {
      public static final String ROLE_VALID_USER = "ROLE_VALID_USER";
  
      @Id
      @GeneratedValue
      private Long id;
  
      @Column
      private String description;
  
      @Column
      private String role;
  
      @ManyToMany
      @JoinTable(name = "granted_permission", 
              joinColumns = {@JoinColumn(name = "GROUP_ID", nullable = false, updatable = false) }, 
              inverseJoinColumns = { @JoinColumn(name = "PERMISSION_ID", nullable = false, updatable = false) })
      private Set&lt;Permission&gt; grantedPermissions;
  
      public Group()
      {
  
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getDescription() {
          return description;
      }
  
      public void setDescription(String description) {
          this.description = description;
      }
  
      public String getRole() {
          return role;
      }
  
      public void setRole(String role) {
          this.role = role;
      }
  
      public Set&lt;Permission&gt; getGrantedPermissions() {
          return grantedPermissions;
      }
  
      public void setGrantedPermissions(Set&lt;Permission&gt; grantedPermissions) {
          this.grantedPermissions = grantedPermissions;
      }
  }
  </code></pre>
  
  <p>Here's the definition of the User class</p>
  
  <pre><code>@Entity
  public class User {
      @Id
      @Column(name="USERNAME")
      private String username;
  
      @Column(name="PASSWORD")
      private String password;
  
      @Transient
      private final boolean enabled = true;
  
      @Column
      private String name;
  
      @Column(name="EMAIL")
      private String email;
  
      @Column(name="PHONE")
      private String phone;
  
      @ManyToOne
      private Group group;
  
      @ManyToOne
      @JoinColumn(name="ORIGINAL_BRANCH_ID")
      private Branch originalBranch;
  
      @ManyToOne
      @JoinColumn(name="ID_OF_RESPONSIBLE_BRANCH")
      private Branch responsibleBranch;
  
      public User()
      {
  
      }
  
      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 String getRole() {
          return group.getRole();
      }
  
      public boolean isEnabled() {
          return enabled;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public String getEmail() {
          return email;
      }
  
      public void setEmail(String email) {
          this.email = email;
      }
  
      public String getPhone() {
          return phone;
      }
  
      public void setPhone(String phone) {
          this.phone = phone;
      }
  
      public Group getGroup() {
          return group;
      }
  
      public void setGroup(Group group) {
          this.group = group;
      }
  
      public Branch getOriginalBranch() {
          return originalBranch;
      }
  
      public void setOriginalBranch(Branch originalBranch) {
          this.originalBranch = originalBranch;
      }
  
      public Branch getResponsibleBranch() {
          return responsibleBranch;
      }
  
      public void setResponsibleBranch(Branch responsibleBranch) {
          this.responsibleBranch = responsibleBranch;
      }
  }
  </code></pre>
  
  <p>Here's the persistence configuration:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"
         xmlns:tx="http://www.springframework.org/schema/tx"
         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/context 
                             http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
  
         &lt;tx:annotation-driven /&gt;
  
         &lt;context:annotation-config /&gt;
  
      &lt;bean id="transactionManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt;
          &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
      &lt;/bean&gt;
  
      &lt;context:component-scan base-package="net.acme.prs" /&gt;
  
      &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"&gt;
          &lt;property name="dataSource" ref="mysqlDataSource" /&gt;
          &lt;property name="packagesToScan" value="net.acme.prs" /&gt;
          &lt;property name="hibernateProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.dialect"&gt;
                      org.hibernate.dialect.MySQL5InnoDBDialect
                  &lt;/prop&gt;
                  &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close"&gt;
          &lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
          &lt;property name="url" value="jdbc:mysql://localhost:3306/prs" /&gt;
          &lt;property name="username" value="" /&gt;
          &lt;property name="password" value="" /&gt;
      &lt;/bean&gt;
  &lt;/beans&gt;
  </code></pre>