简体   繁体   中英

catch LazyInitializationException and throw IllegalStateException, is it a good idea and how to?

In a context of persisted entities with Hibernate, I would like to give more clues to developpers when they get a LazyInitializationException,... no session or session was closed .

I've thought about catching it in the lazily loaded field getter, and then throw a IllegalStateException with a new message :

@OneToMany(mappedBy = "whatever", fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@JoinColumn(name = "USER_ID")
private List<User> userList = new ArrayList<User>();

public List<User> getUserList() {
    try {
        List<User> userList = this.userList;
        return userList ;
    } catch (LazyInitializationException e) {
        throw new IllegalStateException("Here I explain everything", e);
    }
}

IllegalStateException seems to perfectly fit :

Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.

( Source : https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalStateException.html )

But the catch is not reached, can you see why? By the way, is this a good idea?

The catch is not reached because in the getter you don't do more on the List than a standard getter would do.

List<User> userList = this.userList;
return userList ;

Is strictly equivalent to :

return this.userList;

Same code, same behavior.

If you look at the stack of a LazyInitException, you'll see the getter is not the stacktrace, hence, your catch not working as you expect.

The exception happens when you 'use' (like do any method call on) the list : calling size() or iterator() for example.

So add in your getter a size() call.

Do i advise it ? No.

  1. The LazyInitException stacktrace already gives you which field is not loaded : just look at the collection that throw it, and from which field it comes from.
  2. You lose lazy loading (i agree that if you call the getter, you'll want to use the result, but still , this unrelated method call ( size() ) in the getter is a code smell

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM