Bonjour,
j'essaie de remplacer un trigger par un EntityListeners.
Celui-ci doit mettre à jour un stock d'article, lorsque j'ajoute cet article à une liste d'articles commandés.

Mon CRUD fonctionne et donc l'article s'ajoute bien à la liste d'article commandé, mais le stock d'article ne s'adapte pas.

Mon test unitaire, qui ajoute un article à une liste d'articleCommande:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
@Test
    public void test1_insertArticlesCommande() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
        EntityManager em = emf.createEntityManager();
        Client client = em.find(Client.class, 3);
        Article article = em.find(Article.class, 8);
        Controler contr = Controler.getInstance();
        contr.addCommande("2019-10-16", false, 0.00, false, client);//date, cloturée, montant, anullée, idClient
        Commande commande = em.find(Commande.class, 10);
        contr.addArticleCommande(article, commande, 2, 2.65);//idArticle, idCommande, QtyArticle, prixArticle
        System.out.println("TEST1 - articleCommande ajouté dans la DB.");
    }
Mon controler et sa méthode addArticleCommande()
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
/**
     * Ajout d'un article dans la liste d'articleCommande
     * @param idArticle
     * @param idCommande
     * @param qtyArticle
     * @param prixArticle 
     */
    public void addArticleCommande(Article idArticle, Commande idCommande, int qtyArticle, double prixArticle) { 
        ArticleCommande articleCommande = new ArticleCommande(idArticle, idCommande, qtyArticle, prixArticle);
        IntDAO createArticleCommande = DAOFactory.getDAO("ArticleCommandeDAO");
        createArticleCommande.create(articleCommande);
    }
la méthode create de ma Class ArticleCommandeDAO:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
     * Create pour faire l'insert d'un articleCommandé via un requête Hibernate
     * Test avant insert, si un article est inactif, une commande cloturée 
     * ou une Qty d'article commandé > que stock
     *
     * @param entity
     */
    @Override
    public void create(Object entity) {
        ArticleCommande articleCommande = (ArticleCommande) entity;
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");//création EntityManagerFactory.
        EntityManager em = emf.createEntityManager();
        Boolean statusArticle = articleCommande.getIdArticle().status;
        Boolean CommandeCloture = articleCommande.getIdCommande().getCommandeCloturee();
        em.getTransaction().begin();
        try {
            if (statusArticle == false) {//Si un article sélectionné est inactif
                JOptionPane.showMessageDialog(null, "Impossible d'ajouter un article qui n'est plus actif.", "Erreur", JOptionPane.ERROR_MESSAGE);
            } else {
 
            }
            if (CommandeCloture == true) {//Si on essaye d'ajouter un article à une commande cloturée
                JOptionPane.showMessageDialog(null, "Impossible d'ajouter un article à une commande cloturée.", "Erreur", JOptionPane.ERROR_MESSAGE);
            } else {
 
            }
            if (articleCommande.getQtyArticleCommande() > articleCommande.getIdArticle().getStockArticle()) {//Si le stock de l'article sélectionné n'est pas suffisant
                JOptionPane.showMessageDialog(null, "Quantité d'article en stock insufisante.", "Erreur", JOptionPane.ERROR_MESSAGE);
            } else {
 
            }
            if (statusArticle == true && CommandeCloture == false && articleCommande.getQtyArticleCommande() <= articleCommande.getIdArticle().getStockArticle()) {
                em.persist(articleCommande);
                em.getTransaction().commit();
            }
        } catch (Exception ex) {
            em.getTransaction().rollback();
            JOptionPane.showMessageDialog(null, ex, "Message d'erreur", JOptionPane.ERROR_MESSAGE);
        } finally {
            em.close();
        }
    }

ma class ArticleCommande avec le @EntityListeners(ArticleCommandeListener.class)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package be.iepscfjemelle.nicolay.projet_sgdb_v3.model;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
 
/**
 * Classe ArticleCommande, reprend les attributs, accesseurs et constructeurs d'un
 * ArticleCommande. Les mêmes attributs que dans la DB. Avec les annotations pour générer 
 * les tables dans la DB
 * 
 */
@EntityListeners(ArticleCommandeListener.class)//Listener pour adaptation du stock
@Entity
@Table(name = "articles_commandes")
@NamedQueries({
    @NamedQuery(name = "ArticleCommande.findByIdCommande", query = "SELECT ac FROM ArticleCommande ac WHERE ac.idCommande.idCommande = :id")
})
public class ArticleCommande implements Serializable{
 
    private static final long serialVersionUID = 5L;
 
    /**
     * Atrributs
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PK_id_articles_commandes", columnDefinition = "INT(10) UNSIGNED")
    private int idArticleCommande;
    @Column(name = "qty_article_commande", nullable = false, columnDefinition = "INT(10) UNSIGNED")
    private int qtyArticleCommande;
    @Column(name = "prix_actuel_article_commande", nullable = false)
    private Double PrixActuelArticleCommande;
 
    @ManyToOne
    @JoinColumn(name = "FK_Articles_id_articles", referencedColumnName = "PK_id_articles")
    private Article article;
    @ManyToOne
    @JoinColumn(name = "FK_Commandes_id_commandes", referencedColumnName = "PK_id_commandes")
    private Commande idCommande;
 
    /**
     * Constructeur par defaut
     */
    public ArticleCommande() {
    }
 
    /**
     * Constructeur
     * @param idArticleCommande
     * @param qty
     * @param prix 
     */
    public ArticleCommande(int idArticleCommande, int qty, double prix, Article article) {
        this.idArticleCommande = idArticleCommande;
        this.qtyArticleCommande = qty;
        this.PrixActuelArticleCommande = prix;
        this.article = article;
    }
 
    /**
     * Constructeur
     * @param qtyArticleCommande
     * @param prix
     * @param idArticle
     * @param idCommande 
     */
    public ArticleCommande(Article idArticle, Commande idCommande, int qtyArticleCommande, Double prix) {
        this.article = idArticle;
        this.idCommande = idCommande;
        this.qtyArticleCommande = qtyArticleCommande;
        this.PrixActuelArticleCommande = prix;
    }
 
    /**
     * Constructeur
     * @param id
     * @param idArticle
     * @param idCommande
     * @param qtyArticleCommande
     * @param prix
     */
    public ArticleCommande(int id, Article idArticle, Commande idCommande, int qtyArticleCommande, Double prix) {
        this.idArticleCommande = id;
        this.article = idArticle;
        this.idCommande = idCommande;
        this.qtyArticleCommande = qtyArticleCommande;
        this.PrixActuelArticleCommande = prix;
    }
 
    /**
     * Constructeur
     * @param id 
     */
    public ArticleCommande(int id) {
        this.idArticleCommande = id;
    }
 
    /**
     * Accesseurs
     * @return 
     */
    public int getIdArticleCommande() {
        return idArticleCommande;
    }
 
    public void setIdArticleCommande(int idArticleCmmande) {
        this.idArticleCommande = idArticleCmmande;
    }
 
    public int getQtyArticleCommande() {
        return qtyArticleCommande;
    }
 
    public void setQtyArticleCommande(int qtyArticleCommande) {
        this.qtyArticleCommande = qtyArticleCommande;
    }
 
    public Double getPrixActuelArticleCommande() {
        return PrixActuelArticleCommande;
    }
 
    public void setPrixActuelArticleCommande(Double PrixActuelArticleCommande) {
        this.PrixActuelArticleCommande = PrixActuelArticleCommande;
    }
 
    public Article getIdArticle() {
        return article;
    }
 
    public void setIdArticle(Article idArticle) {
        this.article = idArticle;
    }
 
    public Commande getIdCommande() {
        return idCommande;
    }
 
    public void setIdCommande(Commande idCommande) {
        this.idCommande = idCommande;
    }
 
}
Ma class ArticleCommandeListener
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package be.iepscfjemelle.nicolay.projet_sgdb_v3.model;
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PostPersist;
 
/**
 * Listener pour adapter le stock d'un article, quand un article est ajouté,
 * updaté ou supprimer d'une liste d'article commandé.
 *
 */
class ArticleCommandeListener {
 
    @PostPersist
    public void addArticle(ArticleCommande articleCommande) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");//création EntityManagerFactory.
        EntityManager em = emf.createEntityManager();
        Article article = new Article();//création d'un nouvel article
        article = articleCommande.getIdArticle();//faire correspondre nouvel article avec l'article qui est dans articleCommande
        System.out.println("article id:" + article.getIdArticle());
        System.out.println(article.getStockArticle());
        article.setStockArticle(article.getStockArticle() - articleCommande.getQtyArticleCommande());
        System.out.println(article.getStockArticle());
        //em.getTransaction().begin();
 
        try {
            /*em.createQuery("update Article a set a.stockArticle = :newStock where a.idArticle = :id")
                    .setParameter("newStock", article.getStockArticle())
                    .setParameter("id", article.getIdArticle())
                    .executeUpdate();*/
            em.merge(article);
            //em.getTransaction().commit();
        } catch (Exception e) {
            //em.getTransaction().rollback();
        } finally {
            em.close();
        }
    }
}
Dans cette dernière, j'ai vérifier l'id de l'article qui est passé à la liste d'articleCommande, et j'ai vérifier le stock avant et après le article.setStockArticle. à cet endroit là, le stock s'adapte bien.

On dirait que le em.merge(article); ne fonctionne pas.

Si quelqun à l'habitude d'utiliser Hibernate, ses conseils sont les bienvenus, je suis à court d'idées.