Java JPA@PreUpdate@Persist似乎没有按预期工作
我使用@PreUpdate和@PrePersist填写审核字段时遇到问题。例如,当我想更新客户端实体时,字段updatedBy和updatedAt仍然是null;尽管我在调试时执行了@preUpdate注释的preUpdate()代码 下面是负责在每个JPA实体中创建/更新审计字段的代码AuditingField: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
@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和观众更好地理解您的答案?没有问题。没有“现场审计”类别的客户:私人现场审计=新现场审计();这是一个很好的例子,一个专业领域的审计,一个专业领域的审计,一个专业领域的审计!特别是爪哇岛,这里有一个新的解决方案。