web-dev-qa-db-fra.com

Spring Boot + JPA + Hibernate ne se valide pas lorsque repository.save

J'ai une application Spring Boot + JPA avec MySQL. Dans mon contrôleur, lorsque je poste une entité, je peux appeler à repository.save et je renvoie l'objet "créé/mis à jour".

Mais, quand je regarde la base de données, je vois que l'objet n'est pas mis à jour.

Voici mon 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

Savez-vous quoi faire d'autre?

Voici mon contrôleur:

@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);
}

Et MyEntityService:

@Override
@UserCanCud
public Entity save(final Entity entity) {
    Assert.notNull(entity);
    final Entity savedEntity = repository.save(entity);
    return savedEntity;
}
9
Manuelarte

J'ai finalement trouvé la solution ... l'entité que j'essayais de mettre à jour avait l'annotation @Immutable dessus ...

3
Manuelarte

D'après mon expérience (limitée), ces types de problèmes sont un peu plus difficiles à déboguer en raison de la magie qui se passe dans les coulisses de Spring, mais je vais essayer de donner quelques conseils qui m'ont aidé à résoudre des problèmes similaires - j'espère que cela vous donne la Coup de pouce dont vous avez besoin.

Le @Transactional la notation établit une portée transactionnelle qui dicte le début et la fin d'une transaction, également appelée sa limite. Si vous opérez en dehors de cette limite, vous recevrez soit des erreurs, soit les choses ne fonctionneront pas comme prévu.

Tout d'abord, j'ai trouvé ce document le plus utile sur les transactions Spring: http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction. html spécifiquement cette section

Deuxièmement, vous souhaiterez peut-être activer les journaux de niveau de trace et éventuellement les instructions SQL pour faciliter le débogage. Pour ce faire, j'ai ajouté ce qui suit à mon application.properties - Vous pourrez ajouter la même chose dans votre application.yml avec quelques ajustements mineurs

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

Il y aura BEAUCOUP de sortie ici, mais vous aurez une bonne idée de ce qui se passe dans les coulisses.

Troisièmement, et la partie la plus importante pour moi d'apprendre à utiliser @Transactional est que chaque appel au DAO crée une nouvelle session -ou- réutilise la session existante si dans la même portée transactionnelle. Reportez-vous à la documentation ci-dessus pour des exemples de cela.

Maintenant, je soupçonne que votre transaction est toujours considérée comme ouverte lorsque vous relisez votre objet mis à jour. Essayez de faire un flush dans votre méthode de sauvegarde et voyez si cela aide à conserver vos modifications dans la base de données.

J'espère que vous pourrez trouver le problème sans trop chasser en utilisant les ressources ci-dessus, sinon vous devriez au moins avoir des informations plus complètes sur la raison pour laquelle la persistance ne persiste pas.

9
Robert H

Je pense que votre problème réside dans l'interception que vous faites avec l'annotation @UserCanCud.

Je viens de faire un projet avec les mêmes paramètres que vous proposez et cela fonctionne correctement. Jeter un coup d'œil à:

https://github.com/nitzap/spring-data-mysql

Si je manque quelque chose, faites le moi savoir.

1
German