Possible Duplicated
I have this weird bug in my Java Desktop Application, when i use @PrePersist and @PreUpdate all the code from the callback methods is executed, but when i use @PostPersist and @PostUpdate only the System.out.println(...)
code is executed.
Here's my code:
Entity -> Area
import com.pete.bibliogere.modelo.listeners.EntidadeOperacoes;
import com.pete.bibliogere.modelo.listeners.EntidadeOperacoesInterface;
@Entity
@Table(name = "areas")
@EntityListeners(value = EntidadeOperacoes.class)
public class Area implements Serializable, EntidadeOperacoesInterface {
@Column(updatable = false, name = "data_registo")
private LocalDate dataRegisto;
@Column(name = "data_alteracao")
private LocalDate dataAlteracao;
... Some Getters, Setters and other attributes omited...
@Override
public void setDataRegisto(LocalDate data_registo) {
this.data_registo = data_registo;
}
@Override
public void setDataAlteracao(LocalDate data_alteracao) {
this.data_alteracao = data_alteracao;
}
}
Interface for Entities to share the same external EntityListener
public interface EntidadeOperacoesInterface {
public void setDataRegisto(LocalDate data_registo);
public void setDataAlteracao(LocalDate data_alteracao);
}
External EntityListener -> EntidadeOperacoes
public class EntidadeOperacoes {
@PostPersist
public void antesRegistar(EntidadeOperacoesInterface entidade) {
System.out.println("-------- Inserindo data Inserção ------");
entidade.setDataRegisto(LocalDate.now());
System.out.println("-------- Fim Inserção ------");
}
@PostUpdate
public void depoisAlteracao(EntidadeOperacoesInterface entidade) {
System.out.println("-------- Data Atualização ------");
entidade.setDataAlteracao(LocalDate.now());
System.out.println("-------- Fim ------");
}
AreaController
public final class AreaController {
private EntityManager em;
private Validator validator;
private AreaDao dao;
public void registar(String nome, String localizacao) {
validator = ValidatorUtil.getValidator();
em = JpaUtil.getEntityManager();
em.getTransaction().begin();
dao = new AreaServico(em, validator);
dao.registar(new Area(nome.trim(), localizacao.trim()));
em.getTransaction().commit();
em.close();
ValidatorUtil.close();
}
public void alterar(long codigo, String nome, String localizacao) {
validator = ValidatorUtil.getValidator();
em = JpaUtil.getEntityManager();
em.getTransaction().begin();
dao = new AreaServico(em, validator);
dao.atualizar(new Area(codigo, nome, localizacao));
em.getTransaction().commit();
em.close();
ValidatorUtil.close();
}
// Testing Purposes
public static void main(String[] args) {
AreaController ac = new AreaController();
// Persiste area
ac.registar("Area 1", "Localização 1");
}
*AreaServico -> Service Class
public class AreaServico implements AreaDao {
private EntityManager em;
private Validator validator;
public AreaServico(EntityManager em, Validator validator) {
this.em = em;
this.validator = validator;
}
@Override
public void registar(Area area) {
Set<ConstraintViolation<Area>> constraintViolations = validator.validate(area);
if (constraintViolations.iterator().hasNext()) {
JOptionPane.showMessageDialog(null, constraintViolations.iterator().next().getMessage(), "Atenção!", JOptionPane.ERROR_MESSAGE);
} else {
if (areaExiste(area.getNome())) {
JOptionPane.showMessageDialog(null, "Erro: A área digitada já existe."
+ "\nCertifique-se de escolher outro nome!", "Area existente!", JOptionPane.ERROR_MESSAGE);
} else {
em.persist(area);
}
}
}
@Override
public void atualizar(Area area) {
Area areaEncontrada = em.find(Area.class, area.getCodigo());
Set<ConstraintViolation<Area>> constraintViolations = validator.validate(area);
if (areaEncontrada != null) {
if (constraintViolations.iterator().hasNext()) {
JOptionPane.showMessageDialog(null, "Erro: " + constraintViolations.iterator().next().getMessage());
} else {
if (areaExiste(area.getCodigo(), area.getNome())) {
JOptionPane.showMessageDialog(null, "Erro: Já existe uma área com este nome.\n"
+ "Certifique-se de escolher um nome diferente!", "Area existente!", JOptionPane.ERROR_MESSAGE);
} else {
areaEncontrada.setNome(area.getNome());
areaEncontrada.setLocalizacao(area.getLocalizacao());
}
}
} else {
JOptionPane.showMessageDialog(null, "Erro: A área digitada não existe!");
}
}
Here's the console log when i execute the Main method above
Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@37b52340] for TypeConfiguration
select
area0_.codigo as codigo1_0_,
area0_.data_alteracao as data_alt2_0_,
area0_.data_registo as data_reg3_0_,
area0_.localizacao as localiza4_0_,
area0_.nome as nome5_0_
from
areas area0_
where
upper(area0_.nome)=?
binding parameter [1] as [VARCHAR] - [AREA 1]
insert
into
areas
(data_alteracao, data_registo, localizacao, nome)
values
(?, ?, ?, ?)
binding parameter [1] as [DATE] - [null]
binding parameter [2] as [DATE] - [null] /* This shouldn't be null, but LocalDate.now() */
binding parameter [3] as [VARCHAR] - [Localização 1]
binding parameter [4] as [VARCHAR] - [Area 1]
Depois de Inserir registo - Inicio: 1934663431---
Depois de Inserir registo - Fim:1934663440---
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 6.344 s
Finished at: 2020-10-29T09:44:24+02:00
Here's my POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pete</groupId>
<artifactId>BiblioGere</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-agroal</artifactId>
<version>5.4.22.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-osgi-karaf-features</artifactId>
<version>6.1.6.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-cdi</artifactId>
<version>6.1.6.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.4.22.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.15.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
</project>
You set updatable = false
on dataRegisto field so it seems normal the setter doesn't update the value in database.
@PostUpdate is called after fulshing the session. Could you try to add :
@Autowired
private EntityManager entityManager;
And after calling update :
entityManager.flush();
Best regards.