xuyaming
xuyaming

Reputation: 43

failed to lazily initialize a collection of role

@Entity
@Table(name="dt_user" , uniqueConstraints = {@UniqueConstraint(columnNames="user_no"), @UniqueConstraint(columnNames="account")}
)

public class User  implements java.io.Serializable {

/**
 * 
 */
private static final long serialVersionUID = -8149578944942492965L;
// Fields    

 private long id;
 private String userNo;
 private Set<UserRelative> userRelatives = new HashSet<UserRelative>(0);
// Constructors
/** default constructor */
public User() {
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="user")
public Set<UserRelative> getUserRelatives() {
    return this.userRelatives;
}
}

above is user entity;below is another UserRelative entity:when want to getUserRelatives() the problem happens .

@Entity
@Table(name="dt_user_relative")
public class UserRelative  implements java.io.Serializable {
/**
 * 
 */
private static final long serialVersionUID = 5035928604641787267L;
// Fields    

 private long id;
 private User user;
.....

@Id @GeneratedValue(strategy=IDENTITY)
@Column(name="id", unique=true, nullable=false)
public long getId() {
    return this.id;
}

public void setId(long id) {
    this.id = id;
}
@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="user_id")

public User getUser() {
    return this.user;
}

public void setUser(User user) {
    this.user = user;
}
.....
}

my problem is that the error happens when i excute this code :how can i get getRelativeTickets() via userNo?

userDAO.getUserByNo("10001148").getRelativeTickets().size();

public User getUserByNo(String userNo) {
    // TODO Auto-generated method stub
    String query = "from User t where t.userNo=?1";
    List<User> ls = this.findByQuery(query, userNo);
    if (ls.size() > 0)
        return ls.get(0);
    return null;
}

Upvotes: 1

Views: 4090

Answers (1)

Debojit Saikia
Debojit Saikia

Reputation: 10632

Its failing to lazily initialize the collection, because the Hibernate session is getting closed at the end of getUserByNo method - database connection is no longer available, and the object graph is detached. Now when you are calling getRelativeTickets() method, Hibernate can't fetch the association as the session is no longer available and Hibernate does not open a new connection (or session) implicitly to lazy-load the associations.

The recommended solution is to ensure that all the needed associations of the User are fully initialized before returning from getUserByNo method. In HQL, you can specify to eagerly fetch the association by using a from clause fetch join:

String query = "from User t left join fetch t.relativeTickets where t.userNo=?1";

This will return the User with the relativeTickets association fully initialized. With this, the initialization of the association happens in a single SQL statement, so it does not need to hit the DB again to initialize the association.

Upvotes: 5

Related Questions