Slide 1

Slide 1 text

JAKARTA PERSISTENCE API (JPA) &TRANSACTION API (JTA) WITH CDI (VER. 3.1) A part of Jakarta EE specification O-R Mapper and Transaction Framework 1 By Koichi NAKAGAWA Enterprise Web Application Development Course (5)

Slide 2

Slide 2 text

Update Information • Ver. 3: Use Rocky Linux™ instead of CentOS™ as a Linux platform and Payara Server 6™ certified as Jakarta EE 9.1 Platform Compatible Products. • Ver. 2 : Use JDK 11 instead of JDK 8 and Jakarta EE 9 instead of Jakarta EE 8 in all exercises. 2

Slide 3

Slide 3 text

JPA + JTA with CDI Jakarta Persistence API (JPA) and Jakarta Transaction API (JTA) with CDI 3

Slide 4

Slide 4 text

EWA development course curriculum JSF with CDI JPA + JTA with CDI JAX-RS Application Architecture Design Patterns Eclipse IDE™ Version Control Tool with Git™ Build Tool with Apache Maven™ Payara Server™ Administration Windows 10™ + Linux (Rocky Linux™) Total EWA Development Exercise Jakarta Batch Java SE (Oracle JDK™/OpenJDK™) Required Skills to take courses Test Tool with JUnit5 PostgreSQL™ Administration 4 Object Oriented Development Methodology

Slide 5

Slide 5 text

Trademarks Notice • Jakarta™ EE and its logo( ) are trademarks of the Eclipse Foundation. • PostgreSQL™ and its logo( ) are registered trademarks of the PostgreSQL Community Association of Canada. • Apache Derby™ and its logo ( ) are trademarks of the Apache Software Foundation. • Payara™ Server and their logo( ) are trademarks of Payara Services® LTD. • EclipseLink™, EclipseLink™ logo ( ), Eclipse IDE for Enterprise Java Developer™, the Eclipse IDE for Enterprise Java Developer ™ logo( ), Eclipse M2Eclipse™, M2Eclipse™, Eclipse GitTeam Provider™, Eclipse EGit™, EGit™, Eclipse Java development tools™, Java development tools™, Eclipse JDT™, JDT™ are trademarks of the Eclipse Foundation. • Apache Maven™, Maven™ are trademarks of the Apache Software Foundation (ASF). • Git™ and the Git™ logo( ) are either registered trademarks or trademarks of Software Freedom Conservancy, Inc., corporate home of the Git Project, in the United States and/or other countries. • Java™ is trademark of Oracle Corporation. 5

Slide 6

Slide 6 text

Assumption for this course • The trainees who take this course are required the following skills in advance • PostgreSQL (Version: 13.5) – Basic Administration Operations • Payara Server (Version: 6.2021.1.Alpha1) – Basic Administration Operations • Oracle JDK/OpenJDK (Version: 11) • Eclipse IDE for Enterprise Java Developers (Version: 2021-12 (4.22.0)) • Build Tool Training Course • Version Control Tool Training Course • Test Tool Training Course • JSF with CDI Training Course 6

Slide 7

Slide 7 text

Objectives This course is aimed to obtain the following skills • Jakarta Persistence API (JPA) and Jakarta Transaction API (JTA) technology • Jakarta Context Dependency Injection (CDI) technology as components in business layer • Development persistence interface applications using JPA and JTA with CDI 7

Slide 8

Slide 8 text

JPA + JTA with CDI • Design Patterns in Business Layer and Jakarta Persistence API (JPA) • Database Transaction Basics and Jakarta Transaction API (JTA) • Locking Mechanism and Isolation Control and Jakarta Persistence API (JPA) • Design Patterns in Data Access Layer and Jakarta Persistence API (JPA) as O-R Mapper • DB Exception Handling • First JPA DB Application • JPA Entity Relationship Programming • JPA & JTA for CDI Programming • JPA in Jakarta EE Container Programming 8

Slide 9

Slide 9 text

Design Patterns in Business Layer and Jakarta Persistence API (JPA) 9

Slide 10

Slide 10 text

Design Patterns in Business Layer • Analysis Models 10 Retail Sale - name - address - tel. Order - number - date - status OrderItem - count - status 1 * 1 * Ship - count - shipping date - status 1 * Vendor Product HealthCare Product Food Product *

Slide 11

Slide 11 text

Design Patterns in Business Layer • 2 Types of Design Patterns in Business Layer 11 Business Layer Design Patterns Transaction Script Pattern Domain Model Pattern (*) Both patterns of Domain Model and Transaction Script are parts of PofEAA Patterns.

Slide 12

Slide 12 text

Design Patterns in Business Layer • Transaction Script 12 Data Access DAO Business Business Class Name: Vendor: ABC XYZ Update Update Results: Presentation DTO DTO DTO DTO DTO DTO RDB Name ABC Vendor XYZ

Slide 13

Slide 13 text

Design Patterns in Business Layer • Domain Model 13 Data Access O-R Mapper Business Domain Service Presentation Entity/VO Entity/VO RDB Entity/VO Entity/VO Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ DTO DTO

Slide 14

Slide 14 text

Design Patterns in Business Layer • Adopt Onion Architecture based on Domain Driven Architecture (DDD) to Domain Model 14 Data Access O-R Mapper Business Infrastructure Presentation Entity/VO Entity/VO RDB Entity/VO Entity/VO Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ DTO DTO Domain Use Case (Application) Entity/VO Entity/VO Entity/VO Entity/VO

Slide 15

Slide 15 text

Data Access JPA Engine (O-R Mapper) Persistence Context Jakarta Persistence API (JPA) • Entity Manager and Persistence Context 15 Business Domain Service / Infrastructure Entity/VO Entity/VO RDB Entity/VO Entity/VO Entity Manager

Slide 16

Slide 16 text

Jakarta Persistence API (JPA) • Entity Instance Life Cycle 16 Entity State Machine of Entity Instance NEW MANAGED DETACHED REMOVED Product product = new Product() EntityManager#find( Product.class, Primary_Key) EntityManager#persist(product) EntityManager#merge(product) EntityManager#detach(product) EntityManager#clear() EntityManager#persist(product) EntityManager#remove(product)

Slide 17

Slide 17 text

Database Transaction Basics and Jakarta Transaction API (JTA) 17

Slide 18

Slide 18 text

Database Transaction • 2 Transaction Types 18 Short Transaction (Default) • Ex. 1-Click Transaction Long Transaction • Ex. Menu Transition Name: Vendor: ABC XYZ Ltd. Create RDB RDB Name: Vendor: ABC XYZ Ltd. Update Write 1. Read Name: Vendor: A123 AAA Ltd. Save 3. Write 2. After a few minutes

Slide 19

Slide 19 text

Database Transaction • ACID Properties in DBMS for Short Transaction (1) 19 Atomicity • A transaction finishes all the processes inside as completed or rollbacked Consistency • No logical contradiction happens by specifying “Constrains” for RDBMS Order Inventory Transaction Rollback Order Order Detail Consistent

Slide 20

Slide 20 text

Database Transaction • ACID Properties in DBMS for Short Transaction (2) 20 Isolation • Even if multiple transactions for the same entity are executed in parallel, each transaction is not affected each other and processed in serial Durability • Once Data is written into RDBMS, even if it goes down, the Data is never lost Transaction #1 Transaction #2 Each transaction is processed in serial. Order Transaction System Fail! Can be recovered from backups or replications Entity

Slide 21

Slide 21 text

Java Transaction • 2 Java Transaction Types 21 Java Transaction Types JDBC Transaction (with Java SE) JTA Transaction (with Jakarta EE) JTA Transaction Type: RESOURCE_LOCAL Application manages: JTA Transaction Type: JTA Jakarta EE Container manages: -Transactions (Using EntityTransaction obtained from EntityManager) - Persistence Context life cycles (Calling EntityManager#close()/clear()) - Only a Single Persistent Unit in a transaction -Transactions (Transaction behaviors can be declared in CDI or EJB) - Persistence Context life cycles (Application does not need to care) - Multiple Persistent Units or Systems (like JMS, JCA, etc.) in a transaction

Slide 22

Slide 22 text

Java Transaction • JTA Transaction [Managed by Application ] 22 Jakarta EE Container Non-Transactional CDI @Dependent public class orderServiceCDI { @PersistenceContext(…) private EntityManager em; : public void doBusiness(..) { EntityTransaction tx = em.getTransaction(); tx.begin(); try { EntityA entityA = new EntityA(…); em.persist(entityA); : } catch (Exception e) { tx.rollback(); } tx.commit(); } Begin! Commit! RDB SQL #1 SQL #2 ・ ・ ・ Rollback!

Slide 23

Slide 23 text

Java Transaction • JTA Transaction [Managed by Jakarta EE Container] 23 Jakarta EE Container Transactional CDI @ApplicationScoped @Transactional public class orderServiceCDI { @PersistenceContext(…) private EntityManager em; : public void doBusiness(..) { EntityA entityA = new EntityA(…); em.persist(entityA); : } Begin! Commit! RDB SQL #1 SQL #2 ・ ・ ・ Rollback! Declare Transactional CDI XXXXX Done by Jakarta EE Container

Slide 24

Slide 24 text

Java Transaction • Typical 2 JTA Transaction Attributes [@Transactional(TxType.REQUIRED or TxType.REQUIRED_NEW)] 24 Transaction Attribute Caller has not begun Tx yet Caller has already begun Tx TxType.REQUIRED (Default) TxType.REQUIRES_NEW Begin Tx2 Commit Tx2 Begin Tx1 Commit Tx1 Begin Tx2 Commit Tx2 Begin Tx1 Commit Tx1 Begin Tx2 Commit Tx2 Pause Tx1 Resume Tx1 Caller Target Method Caller Target Method Caller Target Method Caller Target Method

Slide 25

Slide 25 text

Transaction and Database Connection • Connection Pool for Performance Improvement • Data Source for Mappings between Transactions and Physical Connections 25 Jakarta EE Container Connection Pool ・ ・ ・ RDB Data Source Jakarta EE Container Connection Pool ・ ・ ・ RDB Data Source 2. PhysicalConnection is kept for a next logical connection Logical Connection (Light Weight) Physical Connection (Heavy Weight) 1. Logical Connection is closed Application Application Manage Mapping Information between Transactions and Physical Connections. (1 Transaction uses 1 Physical Connection)

Slide 26

Slide 26 text

Locking Mechanism and Isolation Control and Jakarta Persistence API (JPA) 26

Slide 27

Slide 27 text

Locking Mechanism and Isolation Control • 2 types of Locking Method and 4 types of Isolation Level 27 Pessimistic Lock • Lock by RDB’s Lock Mechanism (Pessimistic Offline Lock Pattern defined in PofEAA) Optimistic Lock • Lock by Application Logic (Optimistic Offline Lock Pattern defined in PofEAA) Locking Methods • Prevent inconsistency while updating an entity by multiple transactions simultaneously Isolation Level • Prevent illegal transaction interactions SERIALIZABLE REPEATABLE_READ READ_COMMITTED READ_UNCOMMITTED

Slide 28

Slide 28 text

Locking Mechanism • Lock Method [Pessimistic Lock] 28 Transaction A Transaction B Bank Account SELECT FOR UPDATE Balance = 10,000 Balance = Balance + 5,000 UPDATE + COMMIT SELECT FOR UPDATE Wait … Balance = 18,000 Balance = Balance + 3,000 UPDATE + COMMIT Balance = 10,000 SUCCESSFULLY DONE SUCCESSFULLY DONE Balance = 15,000

Slide 29

Slide 29 text

Locking Mechanism • Lock Method [Optimistic Lock] 29 Transaction A Transaction B Bank Account SELECT Balance = 10,000 Balance = Balance + 5,000 UPDATE + COMMIT SELECT Balance = 15,000 Balance = Balance + 3,000 UPDATE + COMMIT Balance = 10,000 Balance = 10,000 SUCCESSFULLY DONE FAILURE

Slide 30

Slide 30 text

Locking Mechanism • Comparison between Lock Methods 30 Lock Type Pessimistic Lock Optimistic Lock When to select? Cases where the same “Entity(a row)” is updated by many transactions at the same time. Other cases, especially for Long Transaction. Dead Lock Possible (Prevent by locking Root Entity or Shared Entity first) Not possible Transaction A Transaction B Entity X Entity Y SELECT FOR UPDATE SELECT FOR UPDATE Wait … Wait … SELECT FOR UPDATE SELECT FOR UPDATE Dead Lock

Slide 31

Slide 31 text

How to set Lock Methods • JPA Programming for Pessimistic Lock 31 Product product = entityManager.find(Product.class, 123, LockModeType.PESSIMISTIC_WRITE); entityManager.flush(); • JPA Programming for Optimistic Lock @Entity public class Product { : @Version private long version; : }

Slide 32

Slide 32 text

Long Transaction with Optimistic Lock • Demo – Long Transaction with Optimistic Lock 32 Order OrderItem 1 * User A User B 2. App: READ 5. App: READ 8. App: WRITE 10. App: WRITE Fail !!! 1. User A: Select an Entity and Click UPDATE 4. User B: Select the same Entity and Click UPDATE 7. User A: Click UPDATE 9. User B: Click UPDATE 3. App: SHOW 6. App: SHOW

Slide 33

Slide 33 text

Short Transaction with Optimistic Lock • Demo – Short Transaction with Optimistic Lock 33 Order User A User B 2. App: INCREMENT 4. App: INCREMENT Fail !!! 1. User A: Select an Entity and Click 3. User B: Select the same Entity and Click in the middle of Step 2

Slide 34

Slide 34 text

Short Transaction with Pessimistic Lock • Demo – Short Transaction with Pessimistic Lock 34 Order User A User B 2. App: INCREMENT 4. App: INCREMENT (Start AFTER Step 2) 1. User A: Select an Entity and Click 3. User A: Select the same Entity and Click in the middle of Step 2 Done

Slide 35

Slide 35 text

Isolation Control • 3 Illegal Transaction Interactions [ANSI/ISO SQL Standard SQL92] 35 Dirty Read • A transaction can read uncommitted data changed by another transaction Non-repeatable Read • A transaction rereads data committed by another transaction and sees the new data Phantom Read • When a query again in a transaction, it can discover new rows inserted or lost existed rows deleted by another transaction

Slide 36

Slide 36 text

Isolation Control • Transaction Interaction [Dirty Read] 36 Transaction A Transaction B Bank Account SELECT Balance = 10,000 Balance = Balance + 5,000 UPDATE SELECT Balance = 10,000 Balance = Balance + 3,000 UPDATE + COMMIT Balance = 15,000 SUCCESSFULLY DONE COMMIT SUCCESSFULLY DONE SUCCESSFULLY DONE Read Before Committed! Balance = 15,000

Slide 37

Slide 37 text

Isolation Control • Transaction Interaction [Non-repeatable Read] 37 Transaction A Transaction B Bank Account SELECT Balance = 10,000 Balance = Balance + 5,000 UPDATE + COMMIT SELECT Balance = 10,000 Balance = Balance + 3,000 UPDATE + COMMIT Balance = 10,000 SUCCESSFULLY DONE SUCCESSFULLY DONE Read Before Committed! SELECT Balance = 15,000 Different data are read in 1 transaction Balance = 18,000

Slide 38

Slide 38 text

Isolation Control • Transaction Interaction [Phantom Read] 38 Transaction A Transaction B Bank Account INSERT ‘A123’ INTO ACCOUNT + COMMIT SELECT * FROM ACCOUNT Account ‘A123’ does NOT EXIST SUCCESSFULLY DONE Read Before Committed! Different data are read in 1 transaction SELECT * FROM ACCOUNT Account ‘A123’ does EXIST (*) The same thing happens for DELETE operation

Slide 39

Slide 39 text

Isolation Control • Comparison among Isolation Levels 39 Isolation Level Dirty Read Non-repeatable Read Phantom Read READ_UNCOMMITTED Possible Possible Possible READ_COMMITTED Not Possible Possible Possible REPEATABLE_READ Not Possible Not Possible Possible SERIALIZABLE Not Possible Not Possible Not Possible Very High High Slow Very Slow Performance (*) Possible cases must be taken care of by applications

Slide 40

Slide 40 text

How to set Isolation Level • Isolation Level Configuration for Jakarta EE (In case of Payara Server) 40

Slide 41

Slide 41 text

Design Patterns in Data Access Layer and Jakarta Persistence API (JPA) as O-R Mapper 41

Slide 42

Slide 42 text

Modeling Domains in Data Access Layer • Logical Object Model and Physical ER Model 42 Vendor Product Impedance Mismatching VENDOR Table PRODUCT Table HealthCare Product Food Product [Object Model] [ER Model] *

Slide 43

Slide 43 text

Design Patterns in Data Access Layer • 2 PofEAA Design Patterns in Data Access Layer 43 Table Data Gateway Pattern • DAO based pattern • OSS Framework: MyBatis Data Mapper Pattern • O-R Mapper based pattern • Jakarta EE Framework: JPA Design Patterns for Data Access Layer

Slide 44

Slide 44 text

Data Mapper Design Pattern • Example of Data Mapper Design Pattern 44 PRODUCT Table ID VER TYPE NAME 1 1 HEALTH Pedometer X1 2 1 FOOD Healthy Drink A 3 2 HEALTH Weight Scale W278 Health Product Pedometer X1 Weight Scale W278 Food Product Healthy Drink A Product O-R Mapper Product HealthCare Product Food Product

Slide 45

Slide 45 text

O-R Mapper Architecture • JPA – Jakarta Persistence API 45 Jakarta EE Container / Java SE JPA Engine Configuration File (persistence.xml) Persistent Context Entity A Entity B Entity C Entity Manager RDB Application CDI EJB

Slide 46

Slide 46 text

O-R Mapper Configuration • JPA Configuration File 46 Configuration File (persistence.xml) org.eclipse.persistence.jpa.PersistenceProvider jdbc/DemoDS JPA Configuration for Jakarta EE org.example.project.domain.Department org.example.project.domain.Employee JPA Configuration for Java SE Transaction Type must be “RESOURCE_LOCAL” and Provider, Entity Classes and DB Connection information should be specified. Provider and Data Source should be specified instead. For Jakarta Persistence 3.0

Slide 47

Slide 47 text

How to obtain EntityManager in CDI? • 2 ways to obtain EntityManager 47 @Dependent public class XXX_Service { : @PersistenceUnit(unitName=“defaultUnit”) private EntityManagerFactory emf; private EntityManager entityManager; : @PostConstruct public void prepare() { entityManager = emf.createEntityManager(); } @PreDestroy public void after(){ entityManager.close(); } public method() { : entityManager.createQuery(“SELECT …”); : } } JTA Transaction Type: RESOURCE_LOCAL (Transaction: Managed by Application) JTA Transaction Type: JTA (Transaction: Managed by Jakarta EE Container) @Dependent @Transactional public class XXX_Service { : @PersistenceContext(unitName=“defaultUnit”) private EntityManager entityManager ; : public method() { : entityManager.createQuery(“SELECT …”); : } } Non-Transactional CDI Transactional CDI Factory Injection Manager Injection Create Close

Slide 48

Slide 48 text

State Machine of JPA Entity Instance • JPA State Transitions of Entity Instance 48 Persistent Context Entity A Entity B Entity C NEW State product = New Product() MANAGED State product = EntityManager.find (Product.class, keyId) DETACHED State EntityManager.persist(product) EntityManager.detach(product) EntityManager.clear() product = EntityManager.merge(product) REMOVED State EntityManager.remove(product) EntityManager.persist(product)

Slide 49

Slide 49 text

JPA Annotations • 2 Ways to define JPA Annotations for Entity Properties (Columns) 49 Persistent Context Entity A Entity B Entity C @Entity public class Product { : @Id private int id; : } @Entity @Table (name=“PRODUCT”) public class Product { : private int id; : @Id @Column(name=“ID”) public int getId() { return id; } : } Annotations for Properties Annotations for Getter Methods Table Name can be specified. Column Name can be specified.

Slide 50

Slide 50 text

JPA Annotations • Auto numbering for Primary Key 50 AUTO IDENTITY SEQUENCE TABLE Strategy In each Entity Class: @Entity public class Product { : @Id  Specify for Primary Key @GeneratedValue(strategy = GenerationType.AUTO) private long id; : } (*) @Id and @GeneratedValue annotation should be specified for the primary key property or getter accessor for it. Specify Auto Numbering Strategy

Slide 51

Slide 51 text

JPA Annotations • Pessimistic Lock and Optimistic Lock (Review) 51 LockType How to use each Lock Type with JPA Pessimistic Lock Product product = entityManager.find (Product.class, productId, LockModeType.PRESSIMISTIC_WRITE); entityManager.flush(); This flush() function call is required to send “SELECT FOR UPDATE” to DB soon. Optimistic Lock In each Entity Class: @Entity public class Product { : @Version private long version; : } This version property or getter accessor for this property with @Version annotation is required. Usually “long” or “int” type is used for this property.  Automatically count up this version field.  Once “Update” on the same Entity by another transaction is detected, “OptimisticLockException” is thrown.

Slide 52

Slide 52 text

JPA Annotations • Relationships (Definition) 52 Product - name - model - description Vendor - Name - address - tel. 1 * @Entity public class Vendor { : @OneToMany(targetEntity = Product.class, mappedBy = “vendor”) private List products; : } @Entity public class Product { : @ManyToOne(targetEntity = Vendor.class) private Vendor vendor; : } The targetEntity is not necessarily specified, as Product.class is defined using Java Generics. This targetEntity is also not necessarily specified, as Vendor.class is the default class in this case. For two-way visibility.

Slide 53

Slide 53 text

. JPA Annotations • Relationships (Manipulation) 53 Product - name - model - description Vendor - name - address - tel. 1 * public void makeNewProduct (name, model, description, venderId) { : Product product = new Product(name, model, description); entityManager.persist(product); Vendor vendor = entityManager.find(Vendor.class, venderId); vendor.getProducts().add(product); product.setVendor(vendor); : } In a function of Transactional CDI Component Set both Entities for two-way visibility.

Slide 54

Slide 54 text

JPA Annotations • Relationships (fetch option) 54 Product - name - model - description Vendor - Name - address - tel. 1 * @Entity public class Vendor { : @OneToMany(targetEntity = Product.class, mappedBy = “vendor”, fetch = FetchType.LAZY) private List products; : } @Entity public class Product { : @ManyToOne(targetEntity = Vendor.class, fetch = FetchType.EAGER) private Vendor vendor; : } 1. Product product = entityManager.find(Product.class, id); 2. Vendor vendor = product.getVendor(); SQL for Vendor Entity is executed at step 1. 1. Vendor vendor = entityManager.find(Vendor.class, id); 2. List products = vendor.getProducts(); SQL for Product Entity is executed at step 2. Default for each Annotation

Slide 55

Slide 55 text

JPA Annotations • Relationships (cascade option) 55 Product - name - model - description Vendor - name - address - tel. 1 * @Entity public class Vendor { : @OneToMany(targetEntity = Product.class, mappedBy = “vendor”, cascade = CascadeType.ALL) private List products; : } @Entity public class Product { : @ManyToOne(targetEntity = Vendor.class) private Vendor vendor; : } 1. Vendor vendor = new Vendor(“ABC Ltd.”, “1-2-3”); 2. Product product = new Product(“AXY”, “A-123”); 3. product.setVendor(vendor); 4. vendor.getProducts().add(product); 5. entityManager.persist(vendor); After vendor is inserted, product is also inserted automatically. (No need to execute entityManager.persist(product).) Select from “ALL”, “PERSIST”, “REMOVE” and “MERGE”

Slide 56

Slide 56 text

JPA Annotations • Relationships (orphanRemoval option) 56 @Entity public class Vendor { : @OneToMany(targetEntity = Product.class, mappedBy = “vendor”, orphanRemoval = true) private List products; : } @Entity public class Product { : @ManyToOne(targetEntity = Vendor.class) private Vendor vendor; : } Product Drink A Vendor ABC Ltd. 2. Drink A becomes Orphan 3. Remove Drink A automatically 1. Remove a relationship with Drink A vendor.getProducts().remove(product);

Slide 57

Slide 57 text

JPA Annotations • Relationships (Inheritance : 3 Strategies) 57 Product HealthCare Product Food Product Single Table Inheritance Product Type Common Fields Healthcare Product Specific Fields Food Product Specific Fields Joined Multiple Table Inheritance ProductType Common Fields Healthcare Product Specific Fields Food Product Specific Fields PRODUCT Table PRODUCT Table HEALTHCARE Table FOOD Table Table Per Class Inheritance All Healthcare Product Fields All Food Product Fields HEALTHCARE Table FOOD Table

Slide 58

Slide 58 text

JPA Annotations • Relationships (Single Table Inheritance) 58 @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = “PRODUCT_TYPE", discriminatorType = DiscriminatorType.STRING) @Entity public class Product { … } @DiscriminatorValue(value = “HEALTHCARE") @Entity public class HealthCareProduct extends Product { … } Product HealthCare Product Food Product @DiscriminatorValue(value = “FOOD") @Entity public class FoodProduct extends Product { … } Single Table Inheritance PRODUCT_TYPE Common Fields Healthcare Product Specific Fields Food Product Specific Fields PRODUCT Table

Slide 59

Slide 59 text

JPA Annotations • Relationships (Joined Multiple Table Inheritance) 59 @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = “PRODUCT_TYPE", discriminatorType = DiscriminatorType.STRING) @Entity public class Product { … } @DiscriminatorValue(value = “HEALTHCARE") @Entity public class HealthCareProduct extends Product { … } Product HealthCare Product Food Product @DiscriminatorValue(value = “FOOD") @Entity public class FoodProduct extends Product { … } Class Table Inheritance PRODUCT Table PRODUCT_TYPE Common Fields Healthcare Product Specific Fields Food Product Specific Fields HEALTHCARE Table FOOD Table

Slide 60

Slide 60 text

JPA Annotations • Relationships (Table Per Class Inheritance) 60 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Entity public class Product { … } @Entity public class HealthCareProduct extends Product { … } Product HealthCare Product Food Product @Entity public class FoodProduct extends Product { … } Concrete Table Inheritance All Healthcare Product Fields All Food Product Fields HEALTHCARE Table FOOD Table

Slide 61

Slide 61 text

JPA Annotations • Relationships (Embeddable Class and Embedded Properties for Value Object) 61 Vendor Address ID NAME ZIP_CODE CITY STREET VENDOR Table Embedded Columns Embeddable Class @Embeddable public class Address { … String zipCode; String city; String street; …} @Entity public class Vendor { : @Embedded @AttributeOverrides({ @AttributeOverride(name = “zipCode", column = @Column(name = “ZIP_CODE") ), @AttributeOverride(name = “city", column = @Column(name = “CITY") ), @AttributeOverride(name = “street", column = @Column(name = “STREET") }) private Address address; : } - zipCode - city - street Optional

Slide 62

Slide 62 text

JPA Annotations • Relationships (Element Collection with Embeddable Class for Collection of Value Objects) 62 Vendor Address ID NAME A1 ABC VENDOR Table Element Collection Embeddable Class @Embeddable public class Address { … @Column(name=“ZIP_CODE") String zipCode; String city; String street; …} @Entity public class Vendor { : @ElementCollection @CollectionTable( name=“ADDRESS", joinColumns=@JoinColumn(name=“COMP_ID")) private List
addresses; : } - zipCode - city - street * Collection COMP_ID ZIP_CODE CITY STREET A1 111-1111 Tokyo 1-1-1 A1 222-2222 Osaka 2-2-2 A1 333-3333 Nagoya 3-3-3 A1 444-4444 Sapporo 4-4-4 ADDRESS Table Optional Optional

Slide 63

Slide 63 text

JPA DB Manipulation Language • 2 Ways to manipulate DB with JPA 63 JPQL (Jakarta Persistence Query Language) • Similar to SQL, so it’s very Easy to Use. Criteria API • Typesafe API, so it’s very Safe to Use.

Slide 64

Slide 64 text

JPA DB Manipulation Language • JPQL(Jakarta Persistence Query Language) 64 Product Query query = entityManager.createQuery( “SELECT p FROM Product p “ + “WHERE p.price <= :maxPrice”) .setParameter(“maxPrice”, 10000); List resultList = query.getResultList(); - int id - String name - String number - int price - String category Query JPQL • Database product independent Query Language  High Portability • Execute complex queries • Execute batch CRUD operations • Possible to execute Database product-native SQLs  But… Low Portability

Slide 65

Slide 65 text

JPA DB Manipulation Language • JPQL – Aggregate Function & Grouping 65 Query query = entityManager.createQuery(“SELECT COUNT(p) FROM Product p”); Long result = (Long)query.getSingleResult(); • Support Grouping with GROUP BY, HAVING Query query = entityManager.createQuery(“SELECT p.category, COUNT(p) “ + “FROM Product p GROUP BY p.category HAVING COUNT(p) > 5”); List resultList = query.getResultList(); Map resultMap = new HashMap(); for (Object[] result: resultList) resultMap.put((String)result[0]), (Long)result[1]); • Supported Aggregate Functions: COUNT, SUM, AVG, MAX, MIN

Slide 66

Slide 66 text

JPA DB Manipulation Language • JPQL – Sorting & Eliminating Duplications 66 Query query = entityManager.createQuery(“SELECT p FROM Product p “ + “ORDER BY p.category, p.price DESC”); List resultList = query.getResultList(); • Support sorting with ORDER BY • Eliminate duplications with DISTINCT Query query = entityManager.createQuery(“SELECT DISTINCT p.category “ + “FROM Product p”); List resultList = query.getResultList();

Slide 67

Slide 67 text

JPA DB Manipulation Language • JPQL – Paging for query results 67 Query query = entityManager.createQuery(“SELECT p FROM Product p ORDER BY p.price DESC”) .setFirstResult(300) .setMaxResults(100); List resultList = query.getResultList(); • Support paging

Slide 68

Slide 68 text

Category Operators/Expressions/Functions Navigation operator . Arithmetic operators +, - (unary plus and minus) *, / (multiplication and division) +, - (addition and subtraction) Comparison operators =, >, >=, <, <=, <> (not equal), [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER [OF] Logical operators NOT AND OR Expressions [NOT] EXISTS (subquery), ALL | ANY | SOME (subquery) String Functions CONCAT(string_primar y, string_primary) | SUBSTRING(string_primar y, simple_arithmetic_expression, simple_arithmetic_expression) | TRIM([[trim_specification] [trim_character] FROM] string_primary) | LOWER(string_primar y) | UPPER(string_primar y) | LENGTH(string_primar y) | LOCATE(string_primar y, string_primar y[, simple_arithmetic_expression]) Arithmetic Functions ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression) Datetime Functions CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP JPA DB Manipulation Language • JPQL – Other Operators/Expressions/Functions 68

Slide 69

Slide 69 text

JPA DB Manipulation Language • JPQL – Relationship with JOIN • Inner Join with [INNER] JOIN Query query = entityManager.createQuery(“SELECT v. name, p.name, “ + “FROM Vendor v INNER JOIN v.products p WHERE p.id = :productId”).setParameter(“productId”, 567); • Outer Join with LEFT [OUTER] JOIN Query query = entityManager.createQuery(“SELECT v. name, p.name, “ + “FROM Vendor v LEFT OUTER JOIN v.products p WHERE p.id = :productId”).setParameter(“productId”, 567); • Fetch Join with [LEFT [OUTER] | INNER] JOIN FETCH Query query = entityManager.createQuery(“SELECT v, “ + “FROM Vendor v JOIN FETCH v.products WHERE v.id = :vendorId”).setParameter(“vendorId”, 123); 69

Slide 70

Slide 70 text

JPA DB Manipulation Language • JPQL – LAZY (N+1 SELECT Problem) 70 Product - name - model - description Vendor - name - address - tel. 1 * Query query = entityManager.createQuery(“SELECT v FROM Vendor AS v”); List vendors = query.gerResultList(); for (Vendor vendor: vendors) { List products = vendor.getProducts();  Execute SQL N times for (Product product: products) { String name = product.getName(); : } } Query query = entityManager.createQuery(“SELECT v FROM Vendor AS v JOIN FETCH v.products”); LAZY fetch Change to use JOIN FECH

Slide 71

Slide 71 text

JPA DB Manipulation Language • JPQL – Batch Delete and Update operations 71 • Batch Deletion with DELETE Query query = entityManager.createQuery(“DELETE FROM Product p WHERE p.price < :price“) .setParameter(“price”, 10000); int hitCount = query.executeUpdate(); • Batch Update with UPDATE Query query = entityManager.createQuery(“UPDATE Product p SET p.price = p.price + :increment “ + “WHERE p.price > :price”).setParameter(“increment”, 100).setParameter(“price”, 10000); int hitCount = query.executeUpdate();

Slide 72

Slide 72 text

JPA DB Manipulation Language • JPQL – Native Query 72 Query query = entityManager.createNativeQuery(“SELECT v.id AS V_ID, v.name AS V_NAME, “ + “p.name AS P_NAME FROM Product p, Vendor v WHERE p.price < :price“, DTOResult.class ) .setParameter(“price”, 10000); List resultList = query.getResultList(); @Entity Public class DTOResult { @Id @Column(name = “V_ID”) private Integer resultId; @Column(name = “V_NAME”) private String resultVName; @Column(name = “P_NAME”) private String resultPName; : }

Slide 73

Slide 73 text

DB Exception Handling 73

Slide 74

Slide 74 text

DB Exception Handling • Sequence Model for Exception Handling 74 Browser Web Application Server Jakarta EE Container RDBMS HTTP Request Fail! SQL Exception HTTP Response Rollback or CommitTx Jakarta EE Container Exception Jakarta EE Container Begin Tx Transaction Boundary Exception Business (Tx CDI) Presentation (Named CDI)

Slide 75

Slide 75 text

Exception Handling in Transaction • Error Types in Transaction and how Jakarta EE Container handles them 75 Expected Error Unexpected Error Unexpected Business Error System Error Infrastructure Error IOException, SQLException, … (Checked Exception) NullPointerException, … (Unchecked Exception) -> Rollback causing Unchecked Exception -> Commit causing Checked Exception in general, otherwise Rollback causing Unchecked Exception Business Rule Error, OptimisticLockException (Unchecked Exception), … Exceptions in data inconsistency, …

Slide 76

Slide 76 text

DB Exception Handling • EJB Exceptions 76 Thrown Exception Class Process Class Type @ApplicationException Rollback attribute *2 Exception which caller receives Transaction MyException1 Checked Don’t Use - MyException1 Commit MyException2 Unchecked Don’t Use - *1 Rollback MyException3 Checked Use False (CDI default) MyException3 Commit MyException4 Checked Use True MyException4 Rollback MyException5 Unchecked Use False MyException5 Commit MyException6 Unchecked Use True (CDI default) MyException6 Rollback *1 MyException2 is wrapped with either javax.ejb.EJBException, java.rmi.RemoteException, javax.ejb.TransactionRolledbackLocalException or javax.transaction.TransactionRolledbackException. *2 For CDI Component, there are “rollbackOn” and “dontRollbackOn” attribute for @Transational to assign specified Exception Classes as rollback class or not rollback class. As default behavior, commit while finishing the method normally or happening checked exceptions, otherwise rollback in case of runtime exception happens.

Slide 77

Slide 77 text

First JPA DB Application Exercise 77

Slide 78

Slide 78 text

First JPA DB Application Development Exercise • Domain Class Model “Department” Entity has a relationship with “Employee” Entity (One-to-Many). 78 Employee - name Department - name * 1 Exercise: Let’s make the First JPA DB Application on Java SE for this Domain Model.

Slide 79

Slide 79 text

First JPA DB Application Development Exercise • Process Flows 1. Have Eclipselink JPA product create a “simpleDb” Database with Apache Derby™ DBMS and “EMPLOYEE” and “DEPARTMENT” Tables in the DB, which are associated with “Employee” and “Department” Entities respectively. 2. Create a “Department” Entity Instance and 2 “Employee” Entity Instances. 79 Employee name: Jakab Gipsz Department name: java name: Captain Nemo ID NAME DEPARTMENT_ID 2 Jakab Gipsz 1 3 Captain Nemo 1 ID NAME 1 java DEPARTMENTTable EMPLOYEETable simpleDb Database DBMS Eclipselink JPA Product(R.I.) Entity Instance Relationships

Slide 80

Slide 80 text

First JPA DB Application Development Exercise • Development Procedure on Eclipse™ 1. Switch Eclipse Workspace to “ws3”, if current Workspace is not “ws3”. 2. Create a project named “jpaproject” using the Archetype (Group Id: com.github.lalyos, Artifact Id: standalone-jpa-eclipselink-archetype, Version: 0.0.2). Set “org.example” as and “0.0.1- SNAPSHOT” as . 3. Modify “pom.xml” to add properties of “project.build.sourceEncoding”, “maven.compiler.source” and “maven.compiler.target” setting “UTF-8”, “11” and “11” respectively. 4. Additionally, modify the following points to upgrade the project to use “Jakarta EE 9.1”. • In the “pom.xml”, for the dependency artifact of “eclipselink”, change to “3.0.2”, and for the dependency artifact of “javax.persistence”, change to “jakarta.persistence” and to “jakarta.persistence-api” and to “3.0.0”. • For all the source files, “Department.java”, “Employee.java” and “JpaTest.Java”, change all the imported classes starting from “javax.persistence” package to ones starting form “jakarta.persistence” package. • For the JPA configuration file of “persistence.xml”, change all the attributes of to use Jakarta Persistence 3.0 and all the under starting from “javax.persistence” package to ones starting form “jakarta.persistence” package. 80

Slide 81

Slide 81 text

First JPA DB Application Development Exercise • Development Procedure on Eclipse™ (Continued) 5. Right click on the project and select “Properties” “Project Facets” and change “Java Version” to “11” and unset “JPA”. Moreover, we need to disable “JPA Configurator” of Maven feature by selecting “Window”  “Preferences”  “Maven”  “Java EE Integration” and unset “JPA Configurator”. This is because current Eclipse IDE has not supported Jakarta Persistence 3.0 yet. 6. Create the target jar file of “jpaproject-0.0.1-SNAPSHOT.jar” by building the “jpaproject” project and execute “JpaTest” main class as “Java Application”, and confirm it has done successfully. Moreover, check the source files to understand how Entities are defined and manipulated. 81 1. Right click on the project “jpaproject” and execute “Run As”  “Run Configurations…” menu and select “Java Application” from left menu. 2. Press “New launch configuration” icon button and set the name to “derby tool” and confirm “jpaproject” is selected as “Project” and select “org.apache.derby.tools.ij” as “Main Class”. 3. Select “Arguments” tab and enter “-p ij.properties” in the “Program Arguments” field and click “Run” button. 4. Type “set SCHEMA JPAPROJECT;” on “ij>” prompt. Then you can use any SQL commands on the prompt. 5. When you finish, type “disconnect;” command without fail.

Slide 82

Slide 82 text

First JPA DB Application Development Exercise • Project Explorer New Derby Database Folder created automatically by executing Java Application Modify Department Entity Class Modify Employee Entity Class Modify 82 Modify Main Class Modify JPA Configuration File

Slide 83

Slide 83 text

JPA Entity Relationship Programming Exercise 83

Slide 84

Slide 84 text

JPA Relationship Programming Exercise • Relationships (cascade option) 84 Employee - name Department - name 1 * @Entity public class Department { : @OneToMany(mappedBy = “department”,cascade = PERSIST) private List employees = new ArrayList(); : } @Entity public class Employee { : @ManyToOne private Department department; : } department = new Department("java"); manager.persist(department); manager.persist(new Employee("Jakab Gipsz",department)); manager.persist(new Employee("Captain Nemo",department)); PERSIST cascade is defined, but not used

Slide 85

Slide 85 text

JPA Relationship Programming Exercise • Relationships (cascade option) 85 @Entity public class Department { : @OneToMany(mappedBy = “department”,cascade = PERSIST) private List employees = new ArrayList(); : } @Entity public class Employee { : @ManyToOne private Department department; : } department = new Department("java"); manager.persist(department); manager.persist(new Employee("Jakab Gipsz",department)); manager.persist(new Employee("Captain Nemo",department)); How to make use of “PERSIST” cascade option? Exercise: Let’s modify the previous JPA DB Application to make use of “PERSIST” cascade option.

Slide 86

Slide 86 text

JPA Relationship Programming Exercise • Development Procedure on Eclipse™ 1. Switch Eclipse Workspace to “ws3”, if current Workspace is not “ws3”. 2. Modify “JpaTest.java” of the “jpaproject” project to make use of “PERSIST” cascade option for “Employee” Entity Class. 3. Build the “jpaproject” project. 4. Remove the “simpleDb” Derby Database folder and execute “JpaTest” main class as “Java Application”, and confirm it has done successfully. 86 num of employess:2 next employee: Employee [id=3, name=Captain Nemo, department=java] next employee: Employee [id=2, name=Jakab Gipsz, department=java] .. done

Slide 87

Slide 87 text

JPA Relationship Programming Exercise • Project Explorer Delete Derby Database Folder before executing Java Application 87 Modify Main Class

Slide 88

Slide 88 text

JPA & JTA for CDI Programming Exercise 88

Slide 89

Slide 89 text

Presentation Named CDI Business Domain Service Transactional CDI JPA & JTA for CDI Unit Test Exercise • Domain Model 89 Data Access O-R Mapper Entity Entity RDB Entity Entity Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ Entity Entity CDI Unit Test Java SE

Slide 90

Slide 90 text

JPA & JTA for CDI Unit Test Exercise • Check if the “manageEmployees()” method of a new “EnterpriseService” CDI class works correctly with “JUnit5” Testing Framework and “Weld-JUnit5” for testing the CDI with JUnit5. @ApplicationScoped public class EnterpriseService { public List manageEmployees() { try { createEmployees(); } catch (Exception e) { e.printStackTrace();} List resultList = listEmployees(); return resultList;} } EnterpriseService.java 90 Exercise: Let’s modify the previous JPA DB Application to make the above new CDI class and test it.

Slide 91

Slide 91 text

JPA & JTA for CDI Unit Test Exercise • Procedure of the Exercise Edit pom.xml Create the EnterpriseService Java Class Make a JUnit Test Class for the EnterpriseService Execute JUnit from Eclipse Execute JUnit from Maven 91

Slide 92

Slide 92 text

JPA & JTA for CDI Unit Test Exercise • Modify the created Maven Object Model file (pom.xml) Add the tag to specify the version “maven-surefire-plugin” to “2.22.2” to support JUnit5 natively.  Add “junit-jupiter-api”, “junit-jupiter-engine” and “hamcrest” as dependency for the JUnit5 testing framework. : org.junit.jupiter junit-jupiter-api 5.8.2 test org.junit.jupiter junit-jupiter-engine 5.8.2 test maven-surefire-plugin 2.22.2 org.hamcrest hamcrest 2.2 test 92

Slide 93

Slide 93 text

JPA & JTA for CDI Unit Test Exercise • Modify the Maven Object Model file (pom.xml) Add “weld-junit5” for JUnit CDI Test and “weld-se-core” for CDI on Java SE as dependency. : org.jboss.weld weld-junit5 3.0.0.Final test org.jboss.weld.se weld-se-core 4.0.2.Final : 93

Slide 94

Slide 94 text

JPA & JTA for CDI Unit Test Exercise • Procedure of the Exercise Edit pom.xml Create the EnterpriseService Java Class Make a JUnit Test Class for the EnterpriseService Execute JUnit from Eclipse Execute JUnit from Maven 94

Slide 95

Slide 95 text

JPA & JTA for CDI Unit Test Exercise • Create a new CDI Java source file (EnterpriseService.java) (1)  The CDI defines EntityManager property and its accessors package org.example.jpaproject.service; import java.util.List; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.EntityManager; import org.example.jpaproject.domain.Department; import org.example.jpaproject.domain.Employee; 95 @ApplicationScoped public class EnterpriseService { private EntityManager manager; public EnterpriseService() { super(); } public EntityManager getManager() { return manager; } public void setManager(EntityManager manager) { this.manager = manager; }

Slide 96

Slide 96 text

JPA & JTA for CDI Unit Test Exercise • Create a new CDI Java source file (EnterpriseService.java) (2)  In the CDI class, add the “manageEmployees()” and “createEmployees()” methods based on the associated functions in “JpaTest.java”. public List manageEmployees() { try { createEmployees(); } catch (Exception e) { e.printStackTrace();} List resultList = listEmployees(); System.out.println(".. done"); return resultList; } 96 private void createEmployees() { int numOfEmployees = manager.createQuery("Select a From Employee a", Employee.class).getResultList().size(); Department department; if (numOfEmployees == 0) { department = new Department("java"); department.getEmployees().add(new Employee("Jakab Gipsz", department)); department.getEmployees().add(new Employee("Captain Nemo", department)); manager.persist(department);} }

Slide 97

Slide 97 text

JPA & JTA for CDI Unit Test Exercise • Create a new CDI Java source file (EnterpriseService.java) (3)  In the CDI class, add the “listEmployees()” method based on the associated function in “JpaTest.java” and modify it to return Employee list as the result of JPQL Query. • Delete a class file of “JpaTest.java” and its package named “org.example.jpaproject.jpa”. 97 private List listEmployees() { List resultList = manager.createQuery("Select a From Employee a", Employee.class).getResultList(); System.out.println("num of employess:" + resultList.size()); for (Employee next : resultList) { System.out.println("next employee: " + next); } return resultList; } • org.example.jpaproject.jpa • JpaTest.java Delete

Slide 98

Slide 98 text

JPA & JTA for CDI Unit Test Exercise • Procedure of the Exercise 98 Edit pom.xml Create the EnterpriseService Java Class Make a JUnit Test Class for the EnterpriseService Execute JUnit from Eclipse Execute JUnit from Maven

Slide 99

Slide 99 text

JPA & JTA for CDI Unit Test Exercise • Create a Test Class folder named “src/test/java” by executing the followings  Right click on the project of “jpaproject” and select “Properties”.  Select “Java Build Path” from left-hand menu of the Properties dialog.  Check a box of “Maven Dependencies” and click “Apply and Close” button. 99

Slide 100

Slide 100 text

JPA & JTA for CDI Unit Test Exercise • Create a Test Resource folder named “src/test/resources” by executing the followings  Right click on the project of “jpaproject” and select “New”  “Source Folder”.  Enter “src/test/resources” and click “Finish” button. 100

Slide 101

Slide 101 text

JPA & JTA for CDI Unit Test Exercise • Create a Test Class file for the created Java source file named “JpaCDITest.java” Right click on the “src/test/java” and select “New  Other…”, then select “Java  JUnit  JUnit Test Case”. Fill “org.example.jpaproject.test” in the Package field and “JpaCDITest” in the Name field and click “Finish” button. 101

Slide 102

Slide 102 text

JPA & JTA for CDI Unit Test Exercise • Modify the Java Test source file (JpaCDITest.java) (1) For the “JpaCDITest” class, add “@EnableWeld”annotation. In the “JpaCDITest” class, setup Weld with “@WeldSetup” and add a property injecting “EnterpriseService” CDI with “@Inject” annotation. package org.example.jpaproject.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.util.List; import jakarta.inject.Inject; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityTransaction; import jakarta.persistence.Persistence; import org.example.jpaproject.domain.Employee; import org.example.jpaproject.service.EnterpriseService; import org.jboss.weld.junit5.EnableWeld; import org.jboss.weld.junit5.WeldSetup; import org.jboss.weld.junit5.WeldInitiator; @EnableWeld class JpaCDITest { @WeldSetup public WeldInitiator weld = WeldInitiator.from(EnterpriseService.class).activate( ApplicationScoped.class).build(); @Inject EnterpriseService service; : 102

Slide 103

Slide 103 text

JPA & JTA for CDI Unit Test Exercise • Modify the Java Test source file (JpaCDITest.java) (2)  In the “JpaCDITest” class, create a method of “testEmployees()” with “@Test” annotation.  Obtain an “EntityManager” and pass it to the “EnterpriseService” CDI.  Add JTA transactional statements before and after executing “EnterpriseService#manageEmployee()”. : @Test void testEmployees() { EntityManager manager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager(); service.setManager(manager); EntityTransaction tx = manager.getTransaction(); tx.begin(); List list = service.manageEmployees(); tx.commit(); assertEquals(2, list.size()); manager.close(); } : } 103

Slide 104

Slide 104 text

JPA & JTA for CDI Unit Test Exercise • Modify the Java Test source file (JpaCDITest.java) (3) In the “JpaCDITest” class, create methods of “setup()” with “@BeforeAll” annotation and “clearup()” with “@AfterAll” annotation and call a private function “clearupDB()” in both methods. Add the “clearupDB()” method above like the following to clear up Entities in the DB. : @BeforeAll static void setup() { clearupDB(); } @AfterAll static void clearup() { clearupDB(); } : 104 : private static void clearupDB() { EntityManager manager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); manager.createQuery("DELETE FROM Employee e").executeUpdate(); manager.createQuery("DELETE FROM Department d").executeUpdate(); tx.commit(); manager.close(); } :

Slide 105

Slide 105 text

JPA & JTA for CDI Unit Test Exercise • Copy the JPA configuration file of “persistence.xml” to “src/test/resources” folder. Right click on the “META-INF” in “src/main/resources” and click “Copy” and then select “src/test/resources” and click “Paste”. Modify the copied “persistence.xml” under “src/test/resources/META-INF” defining target 2 JPA Entity classes with tag. 105 src/test/resources/META-INF/persistence.xml

Slide 106

Slide 106 text

JPA & JTA for CDI Unit Test Exercise • Procedure of the Exercise 106 Edit pom.xml Create the EnterpriseService Java Class Make a JUnit Test Class for the EnterpriseService Execute JUnit from Eclipse Execute JUnit from Maven

Slide 107

Slide 107 text

JPA & JTA for CDI Unit Test Exercise • Execute JUnit directly for the created Java Test source file  Right click on the project and select “Run As”  “2 JUnit Test”  Confirm that JUnit finished successfully checking “Green” flag on “JUnit” tag menu. 107

Slide 108

Slide 108 text

JPA & JTA for CDI Unit Test Exercise • Procedure of the Exercise Edit pom.xml Edit the Score and Calculator Java Class Make a JUnit Test Class for the Score Execute JUnit from Eclipse Execute JUnit from Maven 108

Slide 109

Slide 109 text

JPA & JTA for CDI Unit Test Exercise • Execute JUnit through M2Eclipse™ for the created Java Test source file  Right click on the project and select “Run As”  “3 Maven build” Confirm that test completes successfully in “Console” 109

Slide 110

Slide 110 text

JPA in Jakarta EE Container Programming Exercise 110

Slide 111

Slide 111 text

Presentation Named CDI Business Domain Service Transactional CDI JPA in Jakarta EE System Test Exercise • Domain Model 111 Data Access O-R Mapper Entity Entity RDB Entity Entity Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ Entity Entity Web System Test Jakarta EE Container

Slide 112

Slide 112 text

JPA in Jakarta EE System Test Exercise • Check if the “EXEC JPA” button on a JSF menu works successfully with “JUnit5” Testing Framework and “Selenium-Jupiter” for the integration between Selenium and JUnit5 • The button executes the “manageEmployees()” method of the “EnterpriseService” CDI called from “ViewBean” CDI migrated from the “jsfproject” project. 112 Exercise: Let’s create a new project using the tested CDI class and proceed the web system test for it.

Slide 113

Slide 113 text

JPA in Jakarta EE System Test Exercise • Application Architecture  “PostgreSQL™” instead of “Apache Derby™” as DBMS and “JTA” instead of “LOCAL_RESOURCE” as transaction type are used for the Web System Test (Maven Integration Test).  “LOCAL_RESOURCE” is still used for CDI Unit Test. Therefore different Persistence Units in each JPA Configuration File are required depending on each Maven build phase. 113 Payara Server (Jakarta EE Container) Eclipselink (JPA Framework) Configuration File (persistence.xml) Persistent Context Department Entity Employee Entity Entity Manager Application Enterprise Service CDI PostgreSQL (DBMS) ViewBean CDI AuthBean CDI jsf_jpaPool (Connection Pool) jdbc/jsf_jpa (JDBC Resource) home.xhtml login.xhtml ... Facelets Define Persistence Units for CDI Unit Test and Web System Test Need to check here!!!

Slide 114

Slide 114 text

JPA in Jakarta EE System Test Exercise • This project of “jsf_jpa” is based on the “jsfproject” project and add necessary components from the “jpaproject” project on the Eclipse IDE following the procedure described in the slides form the next page. • Right click on the project and select “Properties” “Project Facets” and unset “JPA”. 114 jsfproject Copy jsf_jpa jpaproject Add • Employee/Department : Entities • EnterpriseService : Service • JpaCDITest : Unit Test • persistence.xml : JPA Config. • …

Slide 115

Slide 115 text

JPA in Jakarta EE System Test Exercise • Procedure of the Exercise Edit pom.xml Copy and Modify persistence.xml and Setup PostgreSQL Create Packages and Copy/Move & Paste Required Files Modify Required Files Execute integration-test from Maven 115

Slide 116

Slide 116 text

JPA in Jakarta EE System Test Exercise • Modify the created Maven Object Model file (pom.xml) Change the artifactId to “jsf_jpa”.  Add “eclipselink”, “jakarta.persistence-api”, “weld-junit5” and “postgresql” with “test” scope as dependency to execute JpaCDITest CDI Unit Test. : org.eclipse.persistence eclipselink 3.0.2 test jakarta.persistence jakarta.persistence-api 3.0.0 test 4.0.0 org.example jsf_jpa war 0.0.1 org.jboss.weld weld-junit5 3.0.0.Final test org.postgresql postgresql 42.3.1 test : 116

Slide 117

Slide 117 text

JPA in Jakarta EE System Test Exercise • Procedure of the Exercise Edit pom.xml Copy and Modify persistence.xml and Setup PostgreSQL Create Packages and Copy/Move & Paste Required Files Modify Required Files Execute integration-test from Maven 117

Slide 118

Slide 118 text

JPA in Jakarta EE System Test Exercise • Modify the JPA configuration file (persistence.xml) Create “src/main/resources” as “Source Folders” and copy “META-INF/persistence.xml” from the “jpaproject” project and paste it to the created folder. Modify the Persistence Unit in the copied persistence.xml like the following for Live Web Application System and Web System Test by Selenium product. org.eclipse.persistence.jpa.PersistenceProvider jdbc/jpaPool false 118 Delete

Slide 119

Slide 119 text

JPA in Jakarta EE System Test Exercise • Modify the JPA configuration file (persistence.xml) for CDI Unit Test Create “src/test/resources” as “Source Folders”, if it does not exist and copy “META- INF/persistence.xml” from the “jpaproject” project and paste it to the created folder. Modify the Persistence Unit in the copied persistence.xml for CDI Unit Test like the following. org.example.jsf_jpa.domain.Department org.example.jsf_jpa.domain.Employee 119 Hostname or IP address of PostgreSQL Server

Slide 120

Slide 120 text

JPA in Jakarta EE System Test Exercise • Setup PostgreSQL making an account of “jpa_exercise” setting its password to “jpa_exercise” with pgAdmin 4.  For the created account, enable the account to login. 120

Slide 121

Slide 121 text

JPA in Jakarta EE System Test Exercise • Setup PostgreSQL making a database of “jpa_db” with pgAdmin 4 Set the owner of the database to the “jpa_exercise” account. 121

Slide 122

Slide 122 text

JPA in Jakarta EE System Test Exercise • Setup Payara Server to accommodate a JDBC Connection Pool of “jpaPool” Set “Resource Type” to “javax.sql.DataSource”, “Database Driver Vendor” to “Postgresql” and “Introspect” to “Enable”. Set required parameters: “DatabaseNamejpa_db”, “Userjpa_exercise”, “Passwordjpa_exercise”, “URLjdbc:postgresql://[hostname or IP]/jpa_db”, “Urljdbc:postgresql://[hostname or IP]/jpa_db” and “ServerName[hostname or IP]” 122 (*) Before configuring Payara Server, be sure that the PostgreSQL JDBC driver module is located in $PAYARA_HOME/glassfish/domains/domain1/lib/.

Slide 123

Slide 123 text

JPA in Jakarta EE System Test Exercise • Setup Payara Server to accommodate a JDBC Resource of “jdbc/jpaPool” Set “Pool Name” to “jpaPool”. 123

Slide 124

Slide 124 text

JPA in Jakarta EE System Test Exercise • Procedure of the Exercise Edit pom.xml Copy and Modify persistence.xml and Setup PostgreSQL Create Packages and Copy/Move & Paste Required Files Modify Required Files Execute integration-test from Maven 124

Slide 125

Slide 125 text

JPA in Jakarta EE System Test Exercise • Refactor package names and Copy required files from the “jpaproject” Create a new “org.example.jsf_jpa.domain” package under the “src/main/java” and copy the “Employee” and “Department” Enitity Classes from the “jpaproject” and paste it to the created new package. Create a new package of “org.example.jsf_jpa.service” under the “src/main/java” folder and copy the “EnterpriseService.java” from the “jpaproject” and paste it to the “org.example.jsf_jpa.service” and change it to import the above Entity Classes. Refactor the package of “org.example.jsfproject” under “src/main/java” to rename it to “org.example.jsf_jpa.view”. Create a new package of “org.example.jsf_jpa.service” under the “src/test/java” folder and copy the “JpaCDITest.java” from the “jpaproject” and paste it to the created package and change it to import an appropriate Entity Class. Refactor the package of “org.example.jsfproject” under “src/test/java” to rename it to “org.example.jsf_jpa.view”. 125

Slide 126

Slide 126 text

JPA in Jakarta EE System Test Exercise • Procedure of the Exercise Edit pom.xml Copy and Modify persistence.xml and Setup PostgreSQL Create Packages and Copy/Move & Paste Required Files Modify Required Files Execute integration-test from Maven 126

Slide 127

Slide 127 text

JPA in Jakarta EE System Test Exercise • Modify Domain Classes (Department.java, Employee.java)  Modify the two Domain Classes to add a Long “version” property with “@Version” annotation to make use of the Optimistic Lock feature. 127 @Entity public class Department { : @Version Long version; : public Long getVersion() { return version;} public void setVersion(Long version) { this.version = version;} : } Add accessors for the “version” property. Declare “version” property (*) We need to do the same thing for Employee Class as well.

Slide 128

Slide 128 text

JPA in Jakarta EE System Test Exercise • Modify EnterpriseService CDI Java source file (EnterpriseService.java)  Define the CDI as a Transactional CDI with @Transactional Obtain EntityManager with @PersistenceContext DI from Jakarta EE Container 128 @Transactional @ApplicationScoped public class EnterpriseService { @PersistenceContext(unitName="persistenceUnit") private EntityManager manager; : public EntityManager getManager() { return manager; } public void setManager(EntityManager manager) { this.manager = manager; } Try to obtain EntityManager with DI from Jakarta EE container. Declare Transactional CDI

Slide 129

Slide 129 text

JPA in Jakarta EE System Test Exercise • Modify JpaCDITest Java source file (JpaCDITest.java)  Change the persistence unit name to “persistenceUnit4Test” for CDI Unit Test 129 @Test void testEmployees() { EntityManager manager = Persistence.createEntityManagerFactory ( "persistenceUnit4Test").createEntityManager(); EntityTransaction tx = manager.getTransaction(); service.setManager(manager); : Specify the new persistence unit name for CDI Unit Test. private static void clearupDB() { EntityManager manager = Persistence.createEntityManagerFactory ("persistenceUnit4Test").createEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); : Specify the new persistence unit name for CDI Unit Test.

Slide 130

Slide 130 text

JPA in Jakarta EE System Test Exercise • Modify ViewBean CDI Java source file (ViewBean.java) (1) Define Employee List of “empList” to show the list of employee and add accessor methods for it. Obtain EnterpriseService CDI of “es” by @Inject Injection. 130 @Named @ViewScoped public class ViewBean implements Serializable { private static final long serialVersionUID = 1L; private float lat = 34.694295f; private float lng = 135.1556805f; private int zoom = 15; private String token; private List empList = new ArrayList(); @Inject private AuthBean authBean; @Inject private EnterpriseService es; private Logger logger = Logger.getLogger(this.getClass().getName()); Add getter and setter for this new field.

Slide 131

Slide 131 text

JPA in Jakarta EE System Test Exercise • Modify ViewBean CDI Java source file (ViewBean.java) (2)  Add a new method of “executeJPA()” to check its token and execute EnterpriseService#manageEmployees() from a JSF Facelets of “home.xhtml”. 131 public void executeJPA() { if (this.token.equals(authBean.getToken())) { String generatedString = generateRandomString(new Random(), 10); this.token = generatedString; authBean.setToken(generatedString); empList = es.manageEmployees(); return; } else { try {ExternalContext ec = FacesContext. getCurrentInstance().getExternalContext(); ec.redirect(ec.getRequestContextPath() + "/faces/login.xhtml"); } catch (IOException e) { e.printStackTrace(); } return; }}

Slide 132

Slide 132 text

JPA in Jakarta EE System Test Exercise • Modify the “home” JSF Facelet file (home.xhtml) (1) Remove the tag by inserting the tag. Add a new tag to execute ViewBean#executeJPA() instead. 132 : : :

Slide 133

Slide 133 text

JPA in Jakarta EE System Test Exercise • Modify the “home” JSF Facelet file (home.xhtml) (2) Remove the tag with the tag. Add a new tag to show ViewBean#empList instead. 133

Slide 134

Slide 134 text

JPA in Jakarta EE System Test Exercise • Modify the system JUnit test file (LoginIT.java) Change the button name executing a JPA operation on the “home” page. 134 : element = driver.findElement(By.id("login")); element.click(); boolean isTitle = wait.until(ExpectedConditions.titleContains("Hello World")); assertTrue(isTitle); Thread.sleep(5000); element = driver.findElement(By.id("executeJPA")); element.click(); Thread.sleep(5000); element = driver.findElement(By.id("logout")); element.click(); isTitle = wait.until(ExpectedConditions.titleContains("Login Menu")); assertTrue(isTitle); Thread.sleep(5000); }

Slide 135

Slide 135 text

JPA in Jakarta EE System Test Exercise • Procedure of the Exercise Edit pom.xml Copy and Modify persistence.xml and Setup PostgreSQL Refactor Package Names and Copy and Modify Required Files Modify ViewBean and home.xhtml Execute integration-test from Maven 135

Slide 136

Slide 136 text

JPA in Jakarta EE System Test Exercise • Execute JUnit through M2Eclipse™ for the created Java Test source file (1)  Right click on the project and select “Run As”  “Maven build …”  Put “jsf_jpa – post-integration-test (Remote)” in “Name” field and “post-integration-test” in “Goals” field and click “Run”. 136

Slide 137

Slide 137 text

JPA in Jakarta EE System Test Exercise • Execute JUnit through M2Eclipse™ for the created Java Test source file (2)  Right click on the project and select “Run As”  “Maven build …”  Put “jsf_jpa – post-integration-test (Local)” in “Name” field and “post-integration-test” in “Goals” field and put “payara6x-local” in “Profile” field and click “Run”. 137

Slide 138

Slide 138 text

Exercise 138

Slide 139

Slide 139 text

Exercise for Managing Related Entities • Required features Create, Update and Remove a “Department” entity. Once one of the entities is removed, the related “Employee” entities are also deleted.  After one of the “Department” entity is selected, Create, Update and Remove an “Employee” entity related with the selected “Department” entity. 139