【问题标题】:Spring Transaction is trying to fire update after select querySpring Transaction 在选择查询后尝试触发更新
【发布时间】:2012-12-04 12:40:46
【问题描述】:

我有一个执行简单选择查询的 DAO 方法:

@Transactional
public List<Object[]> getMyTableData(Long someId)
{
    Session session = (Session) getEntityManager().getDelegate();

    return session
        .createSQLQuery("SELECT * FROM my_table where some_id = :someId")
        .addEntity(MyTable.class)
        .setParameter("someId", someId)
        .list();
}

当我运行它时,我在日志中发现了两个查询:

  1. 成功获取结果的“select * from MyTable where some_id = ...”查询
  2. 然后我在我的日志中找到了这个:

    org.springframework.orm.jpa.JpaTransactionManager:启动事务提交 org.springframework.orm.jpa.JpaTransactionManager:在 EntityManager [org.hibernate.ejb.EntityManagerImpl@162add4] 上提交 JPA 事务 org.hibernate.transaction.JDBCTransaction:提交 org.hibernate.event.def.AbstractFlushingEventListener:处理刷新时间级联 org.hibernate.event.def.AbstractFlushingEventListener:刷新:0 次插入,1 次更新,0 次删除到 2 个对象

然后它会触发另一个查询“Update my_table set ....”

为什么要执行这个更新查询?

【问题讨论】:

  • 大部分日志都表明您的交易正在关闭。由于 Transactional 在 getMyTableData() 方法周围,它将在该方法之前开始一个事务并在最后关闭它(除非调用方法也用 Transactional 注释,在这种情况下它将简单地加入更大的事务)。在 JPA 中,当事务提交时,JPA 会将任何修改后的实体写入数据库。奇怪的是,在您展示的示例中,您根本没有修改查询结果。在您的实际应用程序中,您是否对返回的对象做任何事情?
  • 不,我没有更新结果集中的任何内容。但我发现如果您在事务注释中添加“readOnly = true”,它不会更新您的实体。

标签: java spring hibernate transactions spring-transactions


【解决方案1】:

正如 Pace 上面提到的“在 JPA 中,当事务提交时,JPA 会将任何修改后的实体写入数据库”。所以我尝试将readOnly = true 添加到@Transactional 注释中,它解决了这个问题。

【讨论】:

  • 我有同样的问题,我从视图中选择一行,我得到 Can not modify more base table through a join view ' 错误,我尝试在@transactional 上使用 readOnly=true 但是没用。
猜你喜欢
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多