0

In my grails application in production server I got some issues. In securityFilters I'm injecting springSecurityService and at some point I'm asking something like

if(springSecurityService?.currentUser?.client){
...
}

But system throws an error as

Error 500: Internal Server Error
Class
org.hibernate.LazyInitializationException
Message
could not initialize proxy - no Session
Trace
   Line | Method
->>  32 | doCall            in SecurityFilters$_closure1_closure2_closure4
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    82 | doFilterInternal  in com.linkedin.grails.profiler.ProfilerFilter
|   190 | invoke . . . . .  in org.apache.jk.server.JkCoyoteHandler
|   291 | invoke            in org.apache.jk.common.HandlerRequest
|   776 | invoke . . . . .  in org.apache.jk.common.ChannelSocket
|   705 | processConnection in     ''
|   898 | runIt . . . . . . in org.apache.jk.common.ChannelSocket$SocketConnection
^   636 | run               in java.lang.Thread

line 32 is the place where I call if statement mentioned above. Do you have any clue how to solve this LazyInitializationException? What I am doing wrong?

Note : "client" is the domain class which this user belongs to but it is not mentioned in belongsTo parameter of Person

Thanks.

4

2 回答 2

3

该事件在控制器的 Hibernate 会话之外运行,因此当您加载用户时,它会立即断开连接,并且延迟加载的集合或多对一引用将无法解析。解决此问题的最简单方法是将用户加载调用包装在 withTransaction 块中 - 它使 Hibernate 会话始终保持打开状态:

AnyDomainClass.withTransaction { status ->
   if (springSecurityService?.currentUser?.client) {
      ...
   }
}
于 2012-11-07T15:36:36.453 回答
0

要强制域对象在任何地方都正确工作,您可能需要使用惰性属性。我不知道你的对象是什么样子,但如果有任何类型的对象关系,你可以强迫它们不懒惰。像这样:

class Card {
  static hasMany = [cardProperties: CardProperty]
  static mapping = {
    cardProperties lazy: false
  }
}

为确保您确实有一些可用的会话,您可能需要创建一个事务服务。任何服务都可以,但要确保它不包含该行

static transactional = false

如果您将该服务注入您的过滤器,它将自动创建一个事务并能够获取惰性属性。但要小心!这将开始和完成一个事务。由于您在过滤器中使用它,因此任何页面加载都会多一个事务。

另一种选择是将 sessionFactory bean 注入过滤器。然后,您可以使用纯 Hibernate 语法。就像这个:

sessionFactory.getCurrentSession().beginTransaction();

这不是一个好主意,我不建议这样做,但它可能对你有用。但是请注意,转发请求会导致 2 次交易打开和 2 次交易关闭(这不好)。在决定是否提交事务时,您必须非常小心。但是,如果您确定在应用程序的每个页面上都需要数据库连接 - 这可能对您有用/

于 2012-11-07T15:16:38.787 回答