2 votes

@PrePersist ne fonctionne pas avec @MappedSuperclass dans un environnement Hibernate + Spring

Je crée / enregistre un nouvel utilisateur en utilisant un dépôt dédié :

@Service
public class RegistrationService {

    @Autowired
    private AppUserRepository appUserRepository;

    @Transactional
    public UserCredentialsDto register(UserCredentialsDto userCredentialsDto) {

        String salt = BCrypt.gensalt();
        AppUser appUser = new AppUser();
        appUser.setUsername(userCredentialsDto.getUsername());
        appUser.setPassword(BCrypt.hashpw(userCredentialsDto.getPassword(), salt));

        this.appUserRepository.add(appUser);
        return userCredentialsDto;
    }

}

Le dépôt récupère la Session actuelle depuis le SessionFactory que j'utilise pour save() l'AppUser

@Entity 
public class AppUser externds AbstractTimestampEntity { 
     /* .. */ 
}

comme vous pouvez le voir :

@Repository
public class AppUserRepository {

    @Autowired
    private SessionFactory sessionFactory;

    public void add(AppUser appUser) {
        Session session = sessionFactory.getCurrentSession();
        session.save(appUser);
    }

}

Cependant, j'obtiens

org.postgresql.util.PSQLException: ERROR: null value in column "created" violates not-null constraint
  Detail: Failing row contains (1, null, null, null, $2a$10$0GEFgVryvwG3Dv5LN1tg6evPpl4wQ9uJOWiMKMyZq8HVQXCMRt.kS, null, test).
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2284) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2003) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:133) ~[postgresql-9.4.1208-jdbc42-atlassian-hosted.jar:9.4.1208]
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175) ~[hibernate-core-5.2.11.Final.jar:5.2.11.Final]
    ..

ce qui est dû au fait que created, un champ fourni par AbstractTimestampEntity, est null même s'il aurait dû être défini à la date/heure actuelle avant l'engagement :

@MappedSuperclass
public abstract class AbstractTimestampEntity {

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created", nullable = false)
    @Type(type="org.hibernate.type.ZonedDateTimeType")
    private ZonedDateTime created;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated", nullable = false)
    @Type(type="org.hibernate.type.ZonedDateTimeType")
    private ZonedDateTime updated;

    @PrePersist
    final protected void onCreate() {
        updated = created = ZonedDateTime.now();
    }

    @PreUpdate
    final protected void onUpdate() {
        updated = ZonedDateTime.now();
    }

}

Qu'est-ce que j'ai manqué ici ? Pourquoi @PrePersist ne fonctionne-t-il pas ?

1voto

David Artmann Points 1150

Il semble que l'utilisation de l'API Session ne fonctionne pas avec les rappels JPA que vous utilisez (@PrePersist, @PreUpdate). Hibernate doit être configuré en utilisant un JPA EntityManager.

Article SO utile. Et un autre article utile externe sur le problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X