简体   繁体   中英

JPA - EntityListener - @PrePersist and @PreUpdate work successfully, but @PostPersist and @PostUpdate not working

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM