![](/img/trans.png)
[英]Is it a good idea to open a hibernate session in controller in MVC architecture?
[英]Is it a good idea to close and open hibernate sessions frequently?
我正在开发一个应用程序,它要求以频繁的间隔或触发器从数据库中读取实体状态。 但是,一旦hibernate读取状态,它就不会重新读取它,除非我明确关闭会话并在新会话中读取实体。
每次我想要读取实体然后关闭它时打开一个会话是一个好主意吗? 这会给应用程序和数据库带来多少开销(我们也使用c3p0连接池)?
在再次阅读之前简单地从会话中逐出实体是否足够?
您还可以使用refresh
来重新加载实体。 或evict
和clear
,由@Bozho提及。
使用连接池,打开和关闭会话的开销并不大。 需要时间的是构建会话工厂。
关闭并重新打开会话的问题是,如果我记得很清楚,已经加载的对象仍然会分离。 对于延迟加载,这可能是有问题的。 所以最好保持会话开放并使用evict
, clear
或refresh
。
请注意,如果您逐出实体,并且访问已加载的一个此类实体,您仍将获得旧数据。
MyEntity e = session.load( ... );
...
session.evict(e); // remove entity from the cache
String p = e.myProperty; // still the value at the time it was loaded
e = sesssion.load( ... ); // latest value
在您的情况下,最好引入一个设计指南,表明无论何时操作实体,都应该首先刷新它。
MyEntity e = session.load( ... );
...
session.refresh( e ); // refresh entity and cache
String p = e.myProperty; // latest value
e = sesssion.load( ... ); // latest value
上面的代码只是伪代码,我没有检查过。
请注意,如果会话打开一段时间,缓存可能会增长,在这种情况下,您可能仍希望clear
它。 一般来说,最好保持会话简短以防止缓存增长问题,加上连接超时,事务超时和锁争用问题。
是。 evict()
对象。 如果要清除整个会话,请clear()
它。
新会话应与请求(线程)或长时间运行的会话相关联。
对于链接到其他表的列,如果将fetchtype设置为LAZY,则在明确要求之前,Hibernate不会加载该数据。 这节省了大量时间。
Table
的列可以标记为:
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="other_table_id", nullable = false)
private OtherTable otherTable;
因此,直到你执行类似Table.getOtherTable().getValue()
的操作OtherTable
Table.getOtherTable().getValue()
才会将OtherTable
加载到会话中。 因此,如果你不做某些事情,你也不需要驱逐它。
请注意,这是伪编码,可能会对您的程序有所不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.