Callbacks and Listeners P E N G E M B A N G A N A P L I K A S I E N T E R P R I S E N I K O I B R A H I M F A K U L T A S T E K N O L O G I I N F O R M A S I U N I V E R S I T A S K R I S T E N M A R A N A T H A
Callback & Listener Methods life-cycle callback dan Listener bekerja dengan prinsip yang sama dengan trigger di dalam database. Suatu trigger akan mengeksekusi logika bisnis untuk setiap baris di dalam tabel. Callback dan listener akan dieksekusi untuk setiap instance entity pad saat terjadi suatu event tertentu (sebelum atau sesudah terjadi event) Untuk menentukan waktu eksekusi-nya, kita dapat menggunakan annotations atau XML descriptor, yaitu: Pre dan Post
Callbacks Siklus hidup suatu entitas dapat dibagi ke dalam 4 kategori: persisting, updating, removing, dan loading, yang berkorespondensi dengan operasi database untuk proses: inserting, updating, deleting, and selecting, respectively. Setiap siklus hidup memiliki event Pre dan Post yang dapat dibaca oleh entity manager untuk mengeksekusi fungsi bisnis tertentu.
Life-Cycle Callback Annotations Annotation @PrePersist @PostPersist @PreUpdate @PostUpdate @PreRemove @PostRemove @PostLoad Description Marks a method to be invoked before EntityManager.persist() is executed. Marks a method to be invoked after the entity has been persisted. If the entity autogenerates its primary key (with @GeneratedValue), the value is available in the method. Marks a method to be invoked before a database update operation is performed (calling the entity setters or the EntityManager.merge() method). Marks a method to be invoked after a database update operation is performed. Marks a method to be invoked before EntityManager.remove() is executed. Marks a method to be invoked after the entity has been removed. Marks a method to be invoked after an entity is loaded (with a JPQL query or an EntityManager.find()) or refreshed from the underlying database. There is no @PreLoad annotation, as it doesn t make sense to preload data on an entity that is not built yet.
The Customer Entity with Callback Annotations @Entity public class Customer { @Id @GeneratedValue private Long id; private String firstname; private String lastname; private String email; private String phonenumber; @Temporal(TemporalType.DATE) private Date dateofbirth; @Transient private Integer age; @Temporal(TemporalType.TIMESTAMP) private Date creationdate; Continue
@PrePersist @PreUpdate private void validate() { if (dateofbirth.gettime() > new Date().getTime()) throw new IllegalArgumentException("Invalid date of birth"); if (!phonenumber.startswith("+")) throw new IllegalArgumentException("Invalid phone number"); Continue
@PostLoad @PostPersist @PostUpdate public void calculateage() { if (dateofbirth == null) { age = null; return; Calendar birth = new GregorianCalendar(); birth.settime(dateofbirth); Calendar now = new GregorianCalendar(); now.settime(new Date()); int adjust = 0; if (now.get(gregoriancalendar.day_of_year) - birth.get(gregoriancalendar.day_of_year) < 0) { adjust = -1; age = now.get(gregoriancalendar.year) - birth.get(gregoriancalendar.year) + adjust; // Constructors, getters, setters
Listeners Methods Callback dalam sebuah entitas bermanfaat apabila kita memiliki logika bisnis yang hanya berkaitan dengan entitas tersebut. Entity Listeners digunakan untuk memisahkan logika bisnis ke dalam class tersendiri sehingga dapat di-share dan dimanfaatkan oleh entitas yang lain. Untuk meregistrasi sebuah listener, entitas perlu ditambahkan annotation @EntityListeners.
A Listener Calculating the Customer s Age public class AgeCalculationListener { @PostLoad @PostPersist @PostUpdate public void calculateage(customer customer) { if (customer.getdateofbirth() == null) { customer.setage(null); return; Calendar birth = new GregorianCalendar(); birth.settime(customer.getdateofbirth()); Calendar now = new GregorianCalendar(); now.settime(new Date()); int adjust = 0; if (now.get(gregoriancalendar.day_of_year) - birth.get(gregoriancalendar.day_of_year) < 0) { adjust = -1; customer.setage(now.get(gregoriancalendar.year) - birth.get(gregoriancalendar.year) + adjust);
A Listener Validating the Customer s Attributes public class DataValidationListener { @PrePersist @PreUpdate private void validate(customer customer) { if (dateofbirth.gettime() > new Date().getTime()) throw new IllegalArgumentException("Invalid date of birth"); if (!phonenumber.startswith("+")) throw new IllegalArgumentException("Invalid phone number");
The Customer Entity Defining Two Listeners @EntityListeners({DataValidationListener.class, AgeCalculationListener.class) @Entity public class Customer { @Id @GeneratedValue private Long id; private String firstname; private String lastname; private String email; private String phonenumber; @Temporal(TemporalType.DATE) private Date dateofbirth; @Transient private Integer age; @Temporal(TemporalType.TIMESTAMP) private Date creationdate; // Constructors, getters, setters
Tutorial Program: Callback Methods Buatlah sebuah project baru Java Application (bukan web) Aplikasi ini bertujuan untuk mendemonstrasikan Callback di dalam JPA Ikuti langkah berikut: Buatlah entity class Customer (slide 5) Tambahkan method calculateage dan validate pada entity class tersebut Buatlah sebuah main class untuk mendemonstrasikan input data customer, proses validasi, dan proses perhitungan usia customer ybs. Selamat Mengerjakan