【问题标题】:catch LazyInitializationException and throw IllegalStateException, is it a good idea and how to?捕获 LazyInitializationException 并抛出 IllegalStateException,这是一个好主意吗?怎么做?
【发布时间】:2016-11-14 09:47:49
【问题描述】:

在使用 Hibernate 持久化实体的上下文中,我想在开发人员收到 LazyInitializationException,... no session or session was closed 时为他们提供更多线索。

我考虑过在延迟加载的字段 getter 中捕获它,然后抛出带有新消息的 IllegalStateException :

@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 似乎非常合适:

表示方法已被非法或不适当地调用 时间。换句话说,Java 环境或 Java 应用程序不是 处于请求操作的适当状态。

(来源:https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalStateException.html

但是没有达到目标,你知道为什么吗? 顺便问一下,这是个好主意吗?

【问题讨论】:

    标签: java hibernate exception-handling


    【解决方案1】:

    没有达到目标是因为在 getter 中,您在 List 上做的事情并不比标准 getter 做的多。

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

    严格等价于:

    return this.userList;
    

    相同的代码,相同的行为。

    如果您查看 LazyInitException 的堆栈,您会发现 getter 不是堆栈跟踪,因此,您的 catch 没有按预期工作。

    当您“使用”(就像调用任何方法一样)列表时会发生异常:例如调用 size()iterator()

    所以在你的 getter 中添加一个size() 调用。

    我有什么建议吗?没有。

    1. LazyInitException 堆栈跟踪已经为您提供了未加载的字段:只需查看抛出它的集合,以及它来自哪个字段。
    2. 你失去了延迟加载(我同意如果你调用 getter,你会想要使用结果,但是,getter 中的这个不相关的方法调用 (size()) 是代码异味

    【讨论】:

    • 你是对的,.size() 引发了异常。我同意这个把戏的丑陋可能不值得这些好处。谢谢美人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多