Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tutorial:add_callback [2020/04/21 11:38] (current)
Line 1: Line 1:
  
 +You can easily add **Callback classes** in order to complete <wrap adicode>​persist</​wrap>,​ <wrap adicode>​merge</​wrap>​ or <wrap adicode>​remove</​wrap>​ processes in the EJB.
 +For example, how to automatically set value for <wrap adicode>​lastUpdate</​wrap>​ property in <wrap adicode>​Film</​wrap>​ class when a record is created or updated.
 +\\ \\
 +A **callback class** must extends class <wrap adicode>​org.adichatz.common.ejb.AEntityCallback</​wrap>​. You can override <wrap adicode> preMerge</​wrap>,​ <wrap adicode> prePersist</​wrap>,​ <wrap adicode> preRemove</​wrap>,​
 + <​wrap adicode> postMerge</​wrap>,​ <wrap adicode> postPersist</​wrap>​ or <wrap adicode> postRemove</​wrap>​ methods to finalize processing. Zero, one or more callback classes can be specified to be executed during saving data changes.
 + If you declare several callback classes for an entity,  ​
 +
 +=== Step 1: Create the Callback class ===
 +Create class <wrap adicode>​org.mycompany.myproject.model.callback.FilmCallback</​wrap>​ as below:
 +
 +<sxh java; first-line: 1; highlight: [15,​16,​17,​19,​20,​21];​ title: excerpt from '​FilmCallback.java'​ file (new version).>​
 +package org.mycompany.myproject.model.callback;​
 +
 +import java.util.Date;​
 +
 +import javax.persistence.EntityManager;​
 +
 +import org.adichatz.common.ejb.AEntityCallback;​
 +import org.mycompany.myproject.model.Film;​
 +
 +public class FilmCallback extends AEntityCallback<​Film>​ {
 + public FilmCallback(EntityManager entityManager) {
 + super(entityManager);​
 + }
 + @Override
 + public void preMerge(Film bean) {
 + bean.setLastUpdate(new Date());
 + }
 + @Override
 + public void prePersist(Film bean) {
 + bean.setLastUpdate(new Date());
 + }
 +}
 +</​sxh>​
 +<WRAP indic><​wrap adititle>​Remarks</​wrap>:​\\
 +  * Line 15-17: Sets value for <wrap adicode>​lastUpdate</​wrap>​ property when bean is updated.
 +  * Line 19-21: Sets value for <wrap adicode>​lastUpdate</​wrap>​ property when bean is inserted.
 +</​WRAP>​
 +\\ \\
 +=== Step 2: Change '​FilmMM.axml'​ file ===
 +Open file <wrap adicode>​$projectDirectory/​resources/​xml/​model/​film/​FilmDIMM.xml</​wrap>​.\\ \\
 +**Following XML elements:**
 +<sxh xml; first-line: 1; title: excerpt from '​FilmMMGENERATED.axml'​ file.>
 +<?xml version="​1.0"​ encoding="​UTF-8"​ standalone="​yes"?>​
 +<​entityTree xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 +            entityURI="​adi://​myproject/​model.film/​FilmMM"​ idFieldName="​filmId"​
 +            xsi:​noNamespaceSchemaLocation="​http://​www.adichatz.org/​xsd/​v0.8.7/​generator/​entityTree.xsd">​
 +    <​propertyField mandatory="​true"​ id="​filmId">​
 +    ...
 +    ...
 +</​sxh>​\\
 +\\
 +**Change XML elements**
 +  * Copy <wrap adicode>​FilmMMGENERATED.axml</​wrap>​ file to <wrap adicode>​FilmMM.axml</​wrap>​ which will become the reference for generated code.
 +  * Replace above XML lines with the following ones:
 +<sxh xml; first-line: 1; highlight: [4]; title: excerpt from '​FilmMM.axml'​ file (new version).>​
 +<?xml version="​1.0"​ encoding="​UTF-8"​ standalone="​yes"?>​
 +<​entityTree xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 +            entityURI="​adi://​myproject/​model.film/​FilmMM"​ idFieldName="​filmId"​
 +            callbackClassNames="​org.mycompany.myproject.model.callback.FilmCallback"​
 +            xsi:​noNamespaceSchemaLocation="​http://​www.adichatz.org/​xsd/​v0.8.7/​generator/​entityTree.xsd">​
 +    <​propertyField mandatory="​true"​ id="​filmId">​
 +    ...
 +</​sxh>​
 +<WRAP indic><​wrap adititle>​Remark</​wrap>:​\\
 +Line 4: a Callback class is defined.\\ \\
 +//if you want to set muliple **callback classes** set **callbackClassNames** property with class names separated by comma:// \\
 +<wrap adicode>​callbackClassNames="​org.mycompany.myproject.model.callback.FilmCallback,​ org.mycompany.myproject.model.callback.CommonCallback"</​wrap>​
 +</​WRAP>​
 +\\ \\
 +=== Step 3: Change scenario.xml file for adding callback resources when building EJB ===
 +Open file $projectDirectory/​resources/​xml/​scenario.xml.
 +<sxh xml; first-line: 1; highlight: [3]; title: excerpt from '​scenario.xml'​ file.>
 +    <​actionResources>​
 +    ...
 +        <​copyResource sourceURI="#​PLUGINHOME()/​src/​org/​mycompany/​myproject/​call"​ targetURI="#​EJBJARFILE()!org/​mycompany/​myproject/​call"​ actionWhen="​WHEN_BUILDING_EJB_JAR"​ relative="​false"​ throwError="​false"/>​
 +    </​actionResources>​
 +</​sxh>​
 +<WRAP indic><​wrap adititle>​Remark</​wrap>:​\\
 +Line 3: package <wrap adicode>​org.mycompany.myproject.call</​wrap>,​ containing callback classes is added to **EJB**.</​WRAP>​
 +\\ \\
 +=== Step 4: Build and deploy EJB ===
 +<columns 100% l 450px middle>
 +{{tutorial:​generate_ejb.png?​450| Generate EJB}}
 +<​newcolumn left>
 +  * Open file <wrap adicode>​$projectDirectory/​resources/​xml/​Scenario.xml</​wrap>​ with Adichatz editor.
 +  * {{img_generate_scenario.png| Generate scenario}} Select <wrap adicode>​Generate scenario</​wrap>​ at top right of the editor.
 +  * Check '<​wrap adicode>​Generate EJB</​wrap>'​ and '<​wrap adicode>​DeployEJB on application server</​wrap>'​ options and select '<​wrap adicode>​OK</​wrap>'​ button.
 +</​columns>​
 +\\ \\
 +=== Step 5: Execute ===
 +  * Open editor for <wrap adicode>​Film 1</​wrap>​.
 +  * Change a value and save editor.
 +  * Check that <wrap adicode>​lastUpdate</​wrap>​ property has changed.
 +\\ \\
 +<WRAP adihi>​Callback classes are implemented on the server side. The same principle can be used on the client side using extensions of the class org.adichatz.common.ejb.AEntityForeback and setting class names in **callforeClassNames** property</​WRAP>​