1 Jpa懒加载报错
Caused by: org.apache.tapestry5.runtime.ComponentEventException: could not initialize proxy - no Session
2 报错分析
异常很明确,没有session,那没有session和我们的懒加载和立即加载有什么联系呢?我想大部分的小伙伴都遇到过这个问题,也都能说出答案。
立即加载,他是无论用不用到关联实体,都会将关联实体查出来,这个挺简单的,也不会引发啥异常,但是性能就有点可悲了,因为他啥都能查出来,就像for循环一样,如果不考虑性能,基本没有for循环搞定不了的事。
@ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "tradeRuleId", referencedColumnName = "id", insertable = false, updatable = false) private TradeRule tradeRule;
懒加载,首先懒加载是在查询数据时不会将关联实体直接查出来,而是用的时候查出来。
@OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "sailingScheduleId", referencedColumnName = "id", insertable = false, updatable = false) private Set<Dynamic> dynamics;
如果我使用了懒加载,然后我又要从懒加载的实体上获得其内部属性这会产生什么后果。这就是上面的结果,抛出了异常
Caused by: org.apache.tapestry5.runtime.ComponentEventException: could not initialize proxy - no Session
那为什么是没有session呢,那是因为懒加载必须要有session连接才能获得数据,如果session没有,那就回报错,这下应该很明了了。在使用查询的时候,会获取数据库的连接session,查询后session关闭,但是懒加载的属性并没有在查询的时候查出来,所以读取他的时候就会报错,因为session已经关闭了。
那为什么立即加载就没问题,因为立即加载是查询一次之后,框架会把数据存储在内存中,所以立即加载就不用考虑了。
那又有一个问题,什么叫懒加载在用的时候会去查询?这个问题,我是很疑惑的,后来得到了一个解答。
List<Node> nodeList = ApplicationContextUtil.instance.getJpaUtil().list( "select u.nodeSet from simm.spring.entity.ProcessBlock u where u.id=1", null, Node.class);
以上就是用的时候去查询,也就是针对这个懒加载的实体单独的一个查询。
3 Session
这里面说的是数据库的session,下面说一说的他的运用
比如 Mybatics 的SqlSessionFactory都是拿到session才能去查数据,通透点说就是要登录数据库系统才行,我看网上有的说在service层session是共享的,搞得我去session层去取懒加载的数据,结果还是报错,回头想想这种说法就是错误的,每次查询都说开启一个session然后session在查询后会断开。谈什么service层数据库session共享呢?