当前位置: 首页 > 知识库问答 >
问题:

会话关闭后如何覆盖LAZY加载?

曾景龙
2023-03-14

我使用hibernate并尝试优化加载带注释的外部实体

@ManyToOne(fetch = FetchType.LAZY)

我不想在hibernate查询期间检索外部实体并使用延迟获取类型。稍后(会话已经关闭之后),我想获取那个外部实体,但使用的工具不同于hibernate(另一个缓存的DAO(GuavaCache),它已经存储了外部实体)。

当然,我立即得到了一个LazyLaunalizationException。

我不能用@Transient替换@ManyToOne注释,因为太多的遗留HQL代码在删除@MabyToOne后无法工作。

有人建议将getter方法设为最终方法,不要直接访问实体字段,而只使用getter。这是一个例子:

    private int foreignId;

@Basic
@Column(name = "foregn_id")
public int getForeignId() { return foreignId;}
public void setForeignId(int id) { this.foreignId = id; }


// private DBForeignEntity foreignEntity;  no more sense to have this field

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foregn_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
public final DBForeignEntity getForeign() {
    // return foreignEntity; deprecated usage! Hibernate will create proxy object and throw LazyInitException after session was closed
    return getFromCache(getForeignId());
}

public void setForeign(DBForeignEntity foreignEntity) {
    // this.foreignEntity = foreignEntity;   no more sence for having setter at all
}

这个丑陋的解决方案排除了任何保持嵌套实体的能力,因为不再有外部实体的setter!

是否有另一种方法来反对Hibernate为我的实体创建代理对象?如果会话已关闭,如何避免LazyInitializationException?在这种情况下,不代理是否有任何不良后果?

共有1个答案

汤飞羽
2023-03-14

在当前情况下,hibernate只代理子(foreignEntity)实体,而不代理当前(父)实体。因此,检查外部实体的实例并将其替换为自定义加载的实例是没有问题的:

private int foreignId;

@Basic
@Column(name = "foregn_id")
public int getForeignId() { return foreignId;}
public void setForeignId(int id) { this.foreignId = id; }

private DBForeignEntity foreignEntity;  

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foregn_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
public final DBForeignEntity getForeignEntity() {
    if (foreignEntity instanceof HibernateProxy) {
        foreignEntity = getFromCache(foreignId);
    }
    return foreignEntity;
}

public void setForeign(DBForeignEntity foreignEntity) {
    this.foreignEntity = foreignEntity;   
}

此外,在调用过程中没有LazyInitException

DBParentEntity.getForeignEntity()
 类似资料:
  • 问题内容: 遵循我们在如何在MySQL中关闭sqlalchemy连接中的注释之后,我正在检查SQLAlchemy创建到数据库中的连接,如果不退出Python,我将无法关闭它们。 如果我在python控制台中运行此代码,它将保持会话打开状态,直到我退出python为止: 我发现要关闭它的唯一解决方法是在最后调用。 根据我上面给出的链接中的评论,我的问题现在是: 为什么需要关闭会议? 还不够吗 问题答

  • 问题内容: 加载Web视图后,我需要什么代码来创建对话框? 我试过了 没用 问题答案: :o webview.setWebViewClient(new homeClient()); homeClient() ???? 试试这个 更新:: 这是一个很好的例子。 Android WebView和不确定性进度解决方案

  • 我正在使用spring 4+Websockets+Stomp JS库。我找不到任何方法来设置websocket ping/pong机制(心跳)。 null 因此,我正在实现自己的乒乓消息机制。 这里的任务之一-实现服务器端关闭websocket,以防在超过10秒的时间内没有来自客户端的ping消息。 使用spring WebSockets是没有办法做到这一点的! 也许有人能告诉我如何通过sprin

  • 我们正试图从Spring3/冬眠3升级到Spring4/冬眠4。我们看到的一个问题是,在Hibernate3中,当实体从服务方法周围有事务边界的服务层提取时,实体没有针对延迟加载属性的活动打开会话。事务管理器过去调用SpringSessionSynchronization的afterCompletion来取消设置所有会话。 现在有了spring4Hibernate4组合,我们看到实体带着活跃的开放

  • 我正在使用ActiveMQ对电子邮件进行排队,消费者读取队列并发送电子邮件。 在启动时,我注册一个生产者,并永远缓存它。 有时,当连接关闭时,生产者无法将消息加入队列。 有人能告诉我处理闭门会议的最佳方式吗?我应该重新注册我的制作人吗?还是有办法重开会话?

  • 我有一个Java TLS客户端,它可以向服务器发送一系列请求,每个请求后面都有对服务器的响应。 但是,有许多不同的服务器。有些是“多消息”服务器,在第一个请求后保持连接打开,以便可以通过第一个连接发送后续请求。另一些是“单消息”服务器,在每条消息之后关闭连接,因此后续消息需要新的连接。客户端没有先验的方法来知道它正在与什么类型的服务器通信,也无法修复服务器。 非常希望单个消息服务能够在没有完全握手