Differences
This shows you the differences between two versions of the page.
tutorial:add_callback [2020/04/21 11:38] |
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> |