我有一个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,看看是否有助于将您的更改持久化回数据库。

希望您可以使用上面的资源在不费吹灰之力的情况下找到问题,如果不是这样,那么您至少应该掌握一些有关为何持久性无法持久的更完整的信息。

10-07 19:59
查看更多