我有一个MySQL的Spring Boot Application + JPA。在我的 Controller 中,当我发布一个实体时,我可以调用repository.save,然后返回“创建/更新”的对象。
但是,当我查看数据库时,发现该对象未更新。
这是我的application.yml:
spring:
jpa:
show-sql: true
generate-ddl: false
hibernate:
ddl-auto: none
properties:
hibernate.dialect: org.hibernate.dialect.MySQLDialect
org.hibernate.envers.store_data_at_delete: true
org.hibernate.envers.global_with_modified_flag: true
org.hibernate.envers.track_entities_changed_in_revision: true
datasource:
initialize: false
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:databaseName}?createDatabaseIfNotExist=true
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:root}
driver-class-name: com.mysql.jdbc.Driver
hikari:
minimumIdle: 20
maximumPoolSize: 30
idleTimeout: 5000
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
你知道我还要做什么吗?
这是我的 Controller :
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
public MyEntity saveMyEntity(@Valid @RequestBody final MyEntity myEntity) {
Assert.notNull(myEntity, "The entry cannot be null");
return myEntityService.save(myEntity);
}
和MyEntityService:
@Override
@UserCanCud
public Entity save(final Entity entity) {
Assert.notNull(entity);
final Entity savedEntity = repository.save(entity);
return savedEntity;
}
最佳答案
以我的经验(有限),由于Spring幕后发生的魔力,这些类型的问题很难调试,但我会尽力提供一些可帮助我解决类似问题的建议-希望这可以给您轻按您需要的。@Transactional
表示法建立了一个交易范围,该范围规定了交易的开始和结束时间,也称为交易边界。如果您在此范围之外操作,将会收到错误消息,否则事情将无法正常工作。
首先,我发现以下文档对Spring事务最有帮助:http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html特别是this section
其次,您可能希望启用跟踪级别的日志,并可能启用SQL语句来帮助调试。为了做到这一点,我在application.properties
中添加了以下内容-您可以进行一些较小的调整就将它们添加到application.yml
中
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
spring.jpa.show-sql=true
logging.level.org.hibernate=TRACE
这里会有很多输出,但是您将对幕后发生的事情有个很好的了解。
第三,对我而言,学习如何使用
@Transactional
的最重要部分是,每次对DAO的调用都会创建一个新 session ,或者在相同事务范围内重用现有 session 。有关此示例,请引用上面的文档。现在,我怀疑当您读回更新的对象时,您的事务仍然被认为是开放的。尝试在您的save方法中执行
flush
,看看是否有助于将您的更改持久化回数据库。希望您可以使用上面的资源在不费吹灰之力的情况下找到问题,如果不是这样,那么您至少应该掌握一些有关为何持久性无法持久的更完整的信息。