0

I have two tabeles and I want to fetch on update data from database.
users table(columns):

user_id - username - password - role_id(Foreign Key) - email

user_roles table(columns):

role_id - role

I want to list users in users.jsp . lets see my codes:
User.java

package com.terafast.manager.model;

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Role role;

    public User() {

    }

    public int getId() {
        return id;
    }

    public void setId(int 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 String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

Role.java

package com.terafast.manager.model;

public class Role {
    private int id;
    private String role;

    public Role() {

    }

    public Role(String role) {
        this.role = role;
    }

    public long getId() {
        return id;
    }

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

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.terafast.manager.model">
    <class name="User" table="users">
        <id name="id" column="USER_ID">
            <generator class="native" />
        </id>
        <property name="username" column="USERNAME" />
        <property name="password" column="PASSWORD" />
        <property name="email" column="EMAIL" />

        <many-to-one name="Role" class="com.terafast.manager.model.Role"
            unique="true" not-null="true" column="role_id" />
    </class>
</hibernate-mapping>

Role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.terafast.manager.model">
    <class name="Role" table="user_roles">
        <id name="id" column="role_id">
            <generator class="native" />
        </id>
        <property name="role" />
    </class>
</hibernate-mapping>

This part is from UserDAOImpl that create List of users:

@Override
@Transactional
public List<User> list() {
    @SuppressWarnings("unchecked")
    List<User> listUser = (List<User>) sessionFactory.getCurrentSession().createCriteria(User.class)
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

    return listUser;
}

I already declared public List list(); in UserDAO interface. This is the part that I send List of users to users.jsp from my Controller:

@RequestMapping("/users/show")
public ModelAndView handleRequest() throws Exception {
    List<User> listUsers = userDao.list();
    ModelAndView model = new ModelAndView("panel/users");
    model.addObject("userList", listUsers);
    return model;
}

In jsp file I list Users like this:

<c:forEach var="user" items="${userList}" varStatus="status">
    <tr>
        <td>${status.index + 1}</td>
        <td>${user.username}</td>
        <td>${user.email}</td>
        <td>${user.role}</td>
        <td><a href="edit?id=${user.id}">Edit</a>
            &nbsp;&nbsp;&nbsp;&nbsp; <a href="delete?id=${user.id}">Delete</a>
        </td>
    </tr>
</c:forEach>

So when I run this project as server I got this output:

Hibernate: select this_.USER_ID as USER_ID1_1_0_, this_.USERNAME as USERNAME2_1_0_, this_.PASSWORD as PASSWORD3_1_0_, this_.EMAIL as EMAIL4_1_0_, this_.role_id as role_id5_1_0_ from users this_

and then this error:

Jul 20, 2015 3:32:06 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Could someone explain what is wrong with my program? And how can if I want to add or edit user, what should I do exactly?

PKa
  • 187
  • 2
  • 5
  • 18

2 Answers2

3

By default, all associations are lazy in Hibernate (as opposed to JPA where to-one associations are eager by default).

Either make the association between User and Role eager (lazy="false"):

<many-to-one name="Role" class="com.terafast.manager.model.Role"
   lazy="false" unique="true" not-null="true" column="role_id" />

or explicitly initialize the lazy associations which you intend to use out of the session boundaries:

@SuppressWarnings("unchecked")
List<User> listUser = (List<User>) sessionFactory.getCurrentSession().createCriteria(User.class)
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

for (User user : listUser) {
   Hibernate.initialize(user.getRole());
}

Then in users.jsp, you should use ${user.role.role} to access the value.

Dragan Bozanovic
  • 21,631
  • 4
  • 36
  • 100
  • can you explain lazy in Hibernate? – PKa Jul 20 '15 at 11:04
  • _lazy in Hibernate_ means if you don't use JPA annotations, but define mappings in Hibernate xml (as is your case), then all associations are lazy by default. – Dragan Bozanovic Jul 20 '15 at 11:06
  • And what lazy means totally? – PKa Jul 20 '15 at 11:07
  • [Here](http://stackoverflow.com/questions/2192242/what-is-lazy-loading-in-hibernate) is a nice and brief explanation. For more details, you'll have to go through a Hibernate tutorial; it can't all fit in an answer or a comment. – Dragan Bozanovic Jul 20 '15 at 11:09
  • is any tutorial for my second question? – PKa Jul 20 '15 at 11:19
  • I should get ROLE_ADMIN as result. but I get this "com.terafast.manager.model.Role@fe94a2". Why? – PKa Jul 20 '15 at 11:24
  • It's because it's the `toString` method of `Role` object. You need to access its role attribute: `${user.role.role}`. Regarding your second question, you need to persist/modify the `User` entities in the backend. You'll need to go through a Hibernate tutorial to see how to do it. For frontend part, you'll have to go through a JSP tutorial. Neither of those things can be simply explained in an answer/comment. – Dragan Bozanovic Jul 20 '15 at 12:40
0

Your exception totally depends on Lazy and Eager loading. Set the <many-to-one> relation with property of lazy with false in your user.hbm.xml file.

try this:

<many-to-one name="Role" class="com.terafast.manager.model.Role"
   lazy="false" fetch="select" unique="true" not-null="true" column="role_id" />

and follow @Dragan Bozanovic answer.

michael nesterenko
  • 13,240
  • 23
  • 104
  • 175
msk
  • 112
  • 1
  • 10