Java JPA@PreUpdate@Persist似乎没有按预期工作

Java JPA@PreUpdate@Persist似乎没有按预期工作,java,spring,jpa,spring-data-jpa,Java,Spring,Jpa,Spring Data Jpa,我使用@PreUpdate和@PrePersist填写审核字段时遇到问题。例如,当我想更新客户端实体时,字段updatedBy和updatedAt仍然是null;尽管我在调试时执行了@preUpdate注释的preUpdate()代码 下面是负责在每个JPA实体中创建/更新审计字段的代码AuditingField: @Embeddable @Getter @Setter @NoArgsConstructor public class FieldAuditing implements Serial

我使用@PreUpdate@PrePersist填写审核字段时遇到问题。例如,当我想更新客户端实体时,字段updatedByupdatedAt仍然是null;尽管我在调试时执行了@preUpdate注释的preUpdate()代码

下面是负责在每个JPA实体中创建/更新审计字段的代码AuditingField

@Embeddable
@Getter
@Setter
@NoArgsConstructor
public class FieldAuditing implements Serializable {

    @Column(name = "DATE_CREATION", updatable = false)
    private Instant createdAt;

    @Column(name = "DATE_MODIFICATION", updatable = false)
    private Instant updatedAt;

    @Column(name = "DATE_SUPRESSION", updatable = false)
    private Instant deletedAt;

    @Column(name = "AUTEUR_CREATION", updatable = false, length = 100)
    private String createdBy;

    @Column(name = "AUTEUR_MODIFICATION", updatable = false, length = 100)
    private String updatedBy;

    @Column(name = "AUTEUR_SUPRESSION", updatable = false, length = 100)
    private String deletedBy;

    @Column(name = "IS_SUPPRIMER", nullable = false, updatable = false)
    private boolean isDeleted;

    @PrePersist
    public void prePersist() {
        setCreatedAt(Instant.now());
        setCreatedBy(LoggedInUser.get());
    }

    @PreUpdate
    public void preUpdate() {
        setUpdatedAt(Instant.now());
        setUpdatedBy(LoggedInUser.get());
    }

    @PreRemove
    public void preRemove() {
        setDeletedAt(Instant.now());
        setDeleted(true);
        setDeletedBy(LoggedInUser.get());
    }


}
包含嵌入式审核字段的客户端实体:

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name="TF_CLIENT", schema="dbo")
public class Client implements Serializable {

    private static final long serialVersionUID = 8832848102370267801L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name = "CLT_ID", nullable = false)
    private Long id;

    @Column(name = "CLT_LIBELLE", nullable = false, length = 50, unique = true)
    private String libelle;

    @Temporal(TemporalType.DATE)
    @Column(name = "CLT_DT_OUVERTURE", nullable = false)
    private Date dateOuverture;

    @Temporal(TemporalType.DATE)
    @Column(name = "CLT_DT_FERMETURE")
    private Date dateFermeture;

    @Column(name = "CLT_B_ACTIF")
    private boolean isActif;

    @Embedded
    private FieldAuditing fieldAuditing = new FieldAuditing() ;

   //... rest of another attributes

}
更新客户端实体的方法

private ClientDto save(ClientDto clientDto, Client client) {
        startDateShouldBeBeforeEndDate(clientDto);
        hasUniqueCodePaies(clientDto.getCodePaies());
        Client clientSaved = clientRepository.save(clientMapper.toEntity(clientDto, client));
        clientMapper.addOrRemoveClientActions(clientDto, clientSaved);
        clientMapper.addOrRemoveClientEtats(clientDto, clientSaved);
        clientRepository.save(clientSaved);
        clientDto.setId(clientSaved.getId());
        return clientDto;
    }
最后是持久性上下文配置:

@Configuration
@PropertySource({"classpath:application.yml"})
@EnableJpaRepositories(
        basePackages = "com.github.maaoutir.clientManager",
        entityManagerFactoryRef = "mainEntityManager")
public class PersistenceContext {

    private final Environment env;

    public PersistenceContext(Environment env) {
        this.env = env;
    }

    @Bean
    @Primary
    public DataSource mainDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(Objects.requireNonNull(env.getProperty("spring.datasource.driverClassName")));
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.datasource.password"));
        return dataSource;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean mainEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(mainDataSource());
        em.setPackagesToScan("com.github.maaoutir.clientManager");

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<>();
        // properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect", env.getProperty("spring.jpa.hibernate.dialect"));
        em.setJpaPropertyMap(properties);
        return em;
    }

    @Primary
    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(mainEntityManager().getObject());
        return transactionManager;
    }
}
@配置
@PropertySource({“classpath:application.yml})
@授权代理(
basePackages=“com.github.maaoutir.clientManager”,
entityManagerFactoryRef=“mainEntityManager”)
公共类PersistenceContext{
私人最终环境保护;
公共PersistenceContext(环境环境){
this.env=env;
}
@豆子
@初级的
公共数据源mainDataSource(){
DriverManager数据源dataSource=新的DriverManager数据源();
setDriverClassName(Objects.requireNonNull(env.getProperty(“spring.dataSource.driverClassName”));
setUrl(env.getProperty(“spring.dataSource.url”);
setUsername(env.getProperty(“spring.dataSource.username”);
setPassword(env.getProperty(“spring.dataSource.password”);
返回数据源;
}
@豆子
@初级的
public LocalContainerEntityManagerFactoryBean mainEntityManager(){
LocalContainerEntityManagerFactoryBean em=新的LocalContainerEntityManagerFactoryBean();
em.setDataSource(mainDataSource());
em.setPackagesToScan(“com.github.maaoutir.clientManager”);
HibernateJavaEndorapter vendorAdapter=新的HibernateJavaEndorapter();
em.setjpavendor适配器(供应商适配器);
HashMap属性=新建HashMap();
//properties.put(“hibernate.hbm2ddl.auto”,env.getProperty(“hibernate.hbm2ddl.auto”);
properties.put(“hibernate.dial”,env.getProperty(“spring.jpa.hibernate.dial”);
em.setJpaPropertyMap(属性);
返回em;
}
@初级的
@豆子
公共平台transactionManager transactionManager(){
JpaTransactionManager transactionManager=新的JpaTransactionManager();
transactionManager.SetEntityManager工厂(mainEntityManager().getObject());
返回事务管理器;
}
}

非常感谢您的帮助。

检查您的配置中是否有
@EnableJpaAuditing
,实体类中是否有
@entitylistener(AuditingEntityListener.class)

检查您的配置中是否有
@EnableJpaAuditing
,以及
@EntityListeners(AuditingEntityListener.class)
在实体类上。

在这些列上使用的是
updateable=false

@Column(name = "DATE_MODIFICATION", updatable = false)
private Instant updatedAt;

@Column(name = "AUTEUR_MODIFICATION", updatable = false, length = 100)
private String updatedBy;
这意味着JPA不使用此字段来更新列。从可更新的JPA规范中:

该列是否包含在SQL中 持久化生成的UPDATE语句 提供者


这对于
createdBy
createdAt
列是有意义的,这些列设置在@PrePersist上,并在第一次插入时保持不变,您不希望以后对它们进行修改。但是,如果将
updateable
设置为
false

则@PreUpdate(或@PreRemove)中更新的列不会使用UPDATE语句进行更新,您正在对这些列使用
updateable=false

@Column(name = "DATE_MODIFICATION", updatable = false)
private Instant updatedAt;

@Column(name = "AUTEUR_MODIFICATION", updatable = false, length = 100)
private String updatedBy;
这意味着JPA不使用此字段来更新列。从可更新的JPA规范中:

该列是否包含在SQL中 持久化生成的UPDATE语句 提供者


这对于
createdBy
createdAt
列是有意义的,这些列设置在@PrePersist上,并在第一次插入时保持不变,您不希望以后对它们进行修改。但是,如果
updateable
设置为
false

在类@embeddeble with super中创建构造函数,则@PreUpdate(或@PreRemove)中更新的列将不会使用UPDATE语句进行更新

这对我有用

public FieldAuditing(){
  super();
}

使用super在类@embeddeble中创建构造函数

这对我有用

public FieldAuditing(){
  super();
}

你能解释一下为什么会发生这种情况,以及你的修复程序是如何工作的,以便OP和观众更好地理解你的答案吗。没有“现场审计”类别的客户:私人现场审计=新现场审计();这是一个很好的例子,一个专业领域的审计,一个专业领域的审计,一个专业领域的审计!Não sou specialista em Java,mas foi a soluão que encontrei。请解释为什么会发生这种情况,以及您的修复如何工作,以便OP和观众更好地理解您的答案?没有问题。没有“现场审计”类别的客户:私人现场审计=新现场审计();这是一个很好的例子,一个专业领域的审计,一个专业领域的审计,一个专业领域的审计!特别是爪哇岛,这里有一个新的解决方案。