【发布时间】:2016-11-04 07:38:00
【问题描述】:
在 Spring @RestController 方法中,我尝试在使用 Spring Data CrudRepository 保存实体之前先检查实体是否存在,以便在调用 PUT 到不存在的子资源时返回 404 Not Found 响应存在。如果实体存在,它将尝试保存调用 myObjectDao.save(myObject) 但我收到以下错误:
原因:java.sql.SQLException:连接是只读的。查询 不允许导致数据修改 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2108) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2077) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2062) 在 org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2578)
这是我的存储库和控制器:
public interface MyObjectDao extends CrudRepository<MyObject, Integer> {
}
@RestController
@RequestMapping("my-object")
public class MyObjectRestController {
@Autowired
private MyObjectDao myObjectDao;
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public MyObject update(@PathVariable(value = "id") Integer id,
@RequestBody @Valid MyObject myObject) {
if (!myObjectDao.exists(id)) {
throw new ResourceNotFoundException(String.format("Entity with id %s cannot be found.", id));
}
MyObject.setId(id);
return myObjectDao.save(myObject);
}
似乎一旦调用 myObjectDao.exists(id) 并重用该事务进行保存,Spring 就会将该事务标记为只读。如何检查实体是否存在然后保存而不出现此错误?谢谢!
【问题讨论】:
-
需要你的 dao 代码才能有更好的洞察力。
-
我的道代码在那里。它使用 Spring Data 并且是 MyObjectDao 接口,Spring 在后台提供了实现。
-
我正在使用 org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 但我认为这与它没有任何关系。
-
如果您没有设置事务配置,那么 OpenEntityManagerInViewFilter 可能就是造成这种情况的原因。如果没有设置事务配置,它会以只读执行模式绑定 JPA 实体管理器。来自 javadoc:它适用于通过 TransactionManager 或 JtaTransactionManager 进行的服务层事务以及非事务性只读执行。
-
我将其定义为事务管理器:
标签: hibernate spring-mvc spring-data spring-data-jpa spring-transactions