Hibernate / Spring HibernateTemplate.findByCriteria(Deatched Criteria dc)在视图上执行sql更新

时间:2012-03-21 15:16:43

标签: java hibernate

我正在尝试根据给定的条件搜索视图。此视图为我的应用程序中的多个不同实体提供了一些字段,用户可能希望搜索这些字段。

当我输入我想要搜索的实体的名称时,我会在调用.findByCriteria()之前将名称字段的限制添加到分离的条件中。这会导致.findByCriteria()检索具有我正在寻找的名称的结果列表。

另外,当我查看我的日志时,我可以看到hibernate调用select语句。

我现在已经在我的视图中添加了另一个实体,其中包含一些可搜索的字段。当我尝试搜索与此新实体相关的字段时,我的日志中会出现异常。

当我查看带有异常的日志时,我可以看到hibernate在select之后立即调用带有update语句的select语句(我不是要更新记录,只需在列表中检索它。

那么,当我为新实体调用.findByCriteria()时,为什么hibernate会调用更新?

    
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)

执行的SQL:

休眠:

    select
    * 
from
    ( select
        this_.SEARCH_ID as SEARCH1_35_0_,
        this_.ST_NM as ST24_35_0_ 
    from
        SEARCH_RESULT this_ 
    where
        this_.LOAN_TYPE=? ) 
where
    rownum <= ?
DEBUG 2012-03-21 11:37:19,332 142195  (http-8181-3:org.springframework.orm.hibernate3.HibernateTemplate):
      [org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:389)] 
      Eagerly flushing Hibernate session

DEBUG 2012-03-21 11:37:19,384 142247  (http-8181-3:org.hibernate.SQL):
      [org.hibernate.jdbc.util.SQLStatementLogger.logStatement(SQLStatementLogger.java:111)] 
update
    SEARCH_RESULT 
set
    ADDR_LINE1=?,
    ASSGND_REGION=?,
    BASE_DEAL_ID=?,
    ST_NM=? 
where
    SEARCH_ID=?

1 个答案:

答案 0 :(得分:2)

可能发生了更新,因为Hibernate设置为在执行查询之前执行autoflush,因此如果持久性上下文认为它有脏数据,它将尝试更新它。没有看到我无法确定的代码,但我猜想即使search_result是一个视图,你的相应Java对象也会在getter上注释,并且该对象具有匹配的setter。 Hibernate没有对表和视图进行区分,如果你调用一个setter,Hibernate将假设它有更新的数据更新。

你可以通过添加@Immutable注释(或者hibernate。@ Entity(mutable = false)来调整你为视图构建Java对象的方式,具体取决于你使用的版本。这应该足以表明Hibernate没有刷新更改。您还可以直接注释字段并删除您的setter,以便SearchResult对象的使用者知道它是只读的。