ecom lec4 fall16_jpa

83
E-commerce Systems Instructor: Dr. Zainab Khallouf Java Persistence API Acknowledgements Lecture notes adapted from: [1]. The Java EE 7 Tutorial. [2]. Enterprise JavaBeans 3.1, sixth edition, by Andrew Lee Rubinger, Bill Burke, O'Reilly Media, released: September 2010. [3]. http://netbeans.org/kb/docs/javaee/ecommerce [4]. http://blog.jbaysolutions.com/2011/09/19/jpa-2-relationships-onetomany/ : ة ق ساب ل ا رة ض حا م ل ا ن مA Java EE application server contains three essential containers: Web container, EJBs container, and persistence provider. Figure from: http://netbeans.org/kb/docs/javaee/ecommerce/entity- session.html Introduction to the Java Persistence API ق قُ ح تJava Persistence API (JPA) ن ي ب لة ب ا ق م ل وم ا ه ف م رض غ ا اف ج ى م س0 ي( Entity ( ة0 ي ق5 ب لا ع ات اب0 ي< ب اعدة ف0 ى ف دول و ج) object relational mapping (ORM) ( ة0 اري ر م ت س ود ا ر م ق0 ي ر ط ن ع) persistence provider ل :Q ي م ق ف وا ت م) EclipseLink ، Oracle TopLink و5 اHibernate ...

Upload: zainab-khallouf

Post on 27-Jan-2017

36 views

Category:

Education


0 download

TRANSCRIPT

Page 1: Ecom lec4 fall16_jpa

E-commerce SystemsInstructor: Dr. Zainab Khallouf

Java Persistence APIAcknowledgements

Lecture notes adapted from: [1]. The Java EE 7 Tutorial.[2]. Enterprise JavaBeans 3.1, sixth edition, by Andrew Lee Rubinger, Bill Burke, O'Reilly Media, released: September 2010.[3]. http://netbeans.org/kb/docs/javaee/ecommerce[4]. http://blog.jbaysolutions.com/2011/09/19/jpa-2-relationships-onetomany/

من المحاضرة السابقة:A Java EE application server contains three essential containers: Web container, EJBs container, and persistence provider.

Figure from: http://netbeans.org/kb/docs/javaee/ecommerce/entity-session.html

Introduction to the Java Persistence API تُحققJava Persistence API (JPA)مفهوم المقابلة بين غرض

( و جدول في قاعدة بيانات عالئقية )Entity )يسمى جافاobject relational mapping (ORM)عن طريق مزود )

( متوافق مثل :persistence providerاستمرارية )EclipseLink ، Oracle TopLink أو Hibernate...

An entity class represents a table in a relational database, and each entity instance corresponds to a row in that table.

Page 2: Ecom lec4 fall16_jpa

In the entity, all fields not annotated javax.persistence.Transient or not marked as transient will be persisted to the data store.Example:

public class EntityWithTransientFields {transient int transient3; // not persistent because of transient@Transient int transient4; // not persistent because of @Transient}Requirements for Entity ClassesAn entity class must follow these requirements: The class must be annotated with the

javax.persistence.Entity (@Entity) annotation. The class must have a public or protected, no-argument

constructor. The class may have other constructors. The class must not be declared final. No methods or

persistent instance variables must be declared final. If an entity instance is passed by value, such as through a

session bean's remote business interface, the class must implement the Serializable interface.

Entities may extend both entity and non-entity classes, and non-entity classes may extend entity classes.

Persistent instance variables must be declared private, or protected and can be accessed directly only by the entity class’s methods. Clients must access the entity’s state through getter/setter or business methods.

Each entity has a unique object identifier. (A customer entity, for example, might be identified by a customer number). The unique identifier, or primary key, enables clients to locate a particular entity instance.

Managing Entities

Page 3: Ecom lec4 fall16_jpa

Entities are managed by the entity manager, which is represented by javax.persistence.EntityManager instance.o The EntityManager API creates and removes

persistent entity instances, finds entities by the entity's primary key, and allows queries to be run on entities.

An EntityManager maps a fixed set of classes to a particular database. This set of classes is called a persistence unit.

A persistence unit is defined in a persistence.xml file.o This file is a required deployment descriptor for the

Java Persistence specification. Example:

There are two types of Entity Managers:1. Container-Managed EntityManagers:o An EntityManager can be injected directly into an EJB

using the @javax.persistence.PersistenceContext annotation.

o Example:

2. Application-Managed EntityManagers:(غير مطلوب)

Page 4: Ecom lec4 fall16_jpa

o The EntityManager and its associated persistence context are created and destroyed explicitly by the application.

o To obtain an EntityManager instance, you first must obtain an EntityManagerFactory instance by injecting it into the application component by means of the javax.persistence.PersistenceUnit annotation: @PersistenceUnit

EntityManagerFactory emf; Then obtain an EntityManager from the EntityManagerFactory instance:

EntityManager em = emf.createEntityManager();

In this case, the application needs to access the JTA transaction manager and add transaction information when performing entity operations.

The javax.transaction.UserTransaction interface defines methods to begin, commit, and roll back transactions. Inject an instance of UserTransaction by creating an instance variable annotated with @Resource:

@ResourceUserTransaction utx;

The following example shows how to manage transactions in an application that uses an application-managed entity manager:@PersistenceUnitEntityManagerFactory emf;EntityManager em;@ResourceUserTransaction utx;...em = emf.createEntityManager();try {utx.begin();em.persist(SomeEntity);em.merge(AnotherEntity);em.remove(ThirdEntity);utx.commit();} catch (Exception e) {utx.rollback();}

Persisting Entity Instances New entity instances become managed and persistent

either by invoking the persist method. The entity's data is stored to the database when the

transaction associated with the persist operation is completed.

Synchronizing Entity Data to the Database

Page 5: Ecom lec4 fall16_jpa

To force synchronization of the managed entity to the data store, invoke the flush method of the EntityManager instance.

If the entity is removed, calling flush will remove the entity data from the data store.

Entity Example In NetBeans (Code First Approach): Let's write a JEE 7 application which contains an entity class Account.java and session facade AccountFacade.java, then writing a standalone client.

Step 1:

Page 6: Ecom lec4 fall16_jpa
Page 7: Ecom lec4 fall16_jpa

Step 2:

Page 8: Ecom lec4 fall16_jpa

Step 3:

"create-tables" - will only attempt to create tables, if the table already exists then it will not be dropped or replaced, the existing table will be used.

"drop-and-create-tables" - will first drop the existing table, and then create the new table.

Page 9: Ecom lec4 fall16_jpa

Step 4:Account.java

1 package entities; 2

Page 10: Ecom lec4 fall16_jpa

3 import java.io.Serializable; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.GenerationType; 7 import javax.persistence.Id; 8 9 10 @Entity11 public class Account implements Serializable {12 13 private static final long serialVersionUID = 1L;14 @Id15 @GeneratedValue(strategy = GenerationType.AUTO)16 private Long id;17 private String ownerName;18 private int balance;19 20 public Account() {21 //id = (Long) System.nanoTime();22 }23 24 public int getBalance() {25 return balance;26 }27 28 public void setBalance(int balance) {29 this.balance = balance;30 }31 32 public String getOwnerName() {33 return ownerName;34 }35 36 public void setOwnerName(String ownerName) {37 this.ownerName = ownerName;38 }39 40 public Long getId() {41 return id;42 }43 44 public void setId(Long id) {45 this.id = id;46 }47 48 public void deposit(int amount) {49 balance += amount;

Page 11: Ecom lec4 fall16_jpa

50 }51 52 public int withdraw(int amount) {53 if (amount > balance) {54 return 0;55 } else {56 balance -= amount;57 return amount;58 }59 }60 61 @Override62 public int hashCode() {63 int hash = 0;64 hash += (id != null ? id.hashCode() : 0);65 return hash;66 }67 68 @Override69 public boolean equals(Object object) {70 // TODO: Warning - this method won't work in the case the id fields are not set71 if (!(object instanceof Account)) {72 return false;73 }74 Account other = (Account) object;75 if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {76 return false;77 }78 return true;79 }80 81 @Override82 public String toString() {83 return "entities.Account[ id=" + id + " ]";84 }85 86 }87

Page 12: Ecom lec4 fall16_jpa

Step 5:

AccountFacadeInterface.java

1 package session; 2 3 import entities.Account; 4 import java.util.List; 5 import javax.ejb.Remote; 6 import javax.persistence.Query; 7 @Remote 8 public interface AccountFacadeInterface { 9 10 public Account openAccount(String ownerName, int balance);11 12 public void deposit(int accountNumber, int amount);13 14 public int withdraw(int accountNumber, int amount);15 16 public void close(int accountNumber);17 18 public List<Account> listAccounts();19 }20

Page 13: Ecom lec4 fall16_jpa

AccountFacade.java

1 package session; 2 import entities.Account; 3 import java.io.Serializable; 4 import java.util.List; 5 import javax.ejb.Stateless; 6 import javax.ejb.LocalBean; 7 import javax.persistence.EntityManager; 8 import javax.persistence.PersistenceContext; 9 import javax.persistence.Query;10 11 @Stateless12 public class AccountFacade implements AccountFacadeInterface{13 14 @PersistenceContext(unitName = "AccountEntitySample-ejbPU")15 private EntityManager em;16 17 public Account openAccount(String ownerName, int balance) {18 Account account = new Account();19 account.setOwnerName(ownerName);20 account.setBalance(balance);21 em.persist(account);22 return account;23 }24 25 public void deposit(int accountNumber, int amount) {26 Account account = em.find(Account.class, accountNumber);27 account.deposit(amount);28 }29 30 public int withdraw(int accountNumber, int amount) {31 Account account = em.find(Account.class, accountNumber);32 return account.withdraw(amount);33 }34 35 public void close(int accountNumber) {36 Account account = em.find(Account.class, accountNumber);37 em.remove(account);38 }39 40 public List<Account> listAccounts() {41 Query query = em.createQuery("SELECT a FROM Account a");42 return query.getResultList();

Page 14: Ecom lec4 fall16_jpa

43 }44 }45

Step 6:

Now we can see the generated Account table.

Step 7:The standalone client.

Page 15: Ecom lec4 fall16_jpa

Entity Example In NetBeans (Database First Approach): -Generating Entities from a database, then generating the facade session beans. This approach is illustrated in the following snapshots:

Page 16: Ecom lec4 fall16_jpa
Page 17: Ecom lec4 fall16_jpa
Page 18: Ecom lec4 fall16_jpa

Primary Keys in Entities Every entity must have a primary key. An entity may have either a simple or

a composite primary key.

Simple primary keys

Use the javax.persistence.Id (@Id) annotation to denote the primary key field.

Primary key can be generated manually or by the persistence provider. Generating the Primary Key ManuallyExample:

C:\Projects_lecEntities\BankEntityWebApplication\src\java\entities\Account.java 1 package entities; 2 import java.io.Serializable; 3 import javax.persistence.Entity; 4 import javax.persistence.Id; 5 @Entity 6 public class Account implements Serializable { 7 private static final long serialVersionUID = 1L; 8 private long id; 9 private String ownerName;10 private int balance;11 public Account() {12 id = (long) System.nanoTime();13 }....26 @Id27 public long getId() {28 return id;

Page 19: Ecom lec4 fall16_jpa

29 }30 public void setId(long id) {31 this.id = id;32 }... }

Generating the Primary Key by the Persistence Provider When you want provider-generated keys, you have to use

the @javax.persistence.GeneratedValue annotation. For example:

GenerationType can take one of the following values: 1. Table: The TABLE strategy tells the container to use a

user-defined relational table from which the primary keys will be generated.

2. Sequence: In some RDBMSs like Oracle, you can create a sequence object that is used to generate a number sequence.

3. Identity: In MySQL you can create identity column

4. Auto : The GeneratorType.AUTO strategy is the most commonly used configuration, and it is the default. This strategy tells the persistence provider that you are allowing it to generate the key for you.

Composite primary keys:

Composite primary key is composed of multiple persistent properties.

Example:

Page 20: Ecom lec4 fall16_jpa

o A Customer entity can be identified by both its last name and its social security number.

The Java Persistence specification provides two ways to define a composite primary key.

1. Through the: @javax.persistence.IdClass annotation. 2. Through the: @javax.persistence.EmbeddedId

annotation.@IdClass @IdClass is a class-level annotation and identifies the

primary-key class. In the entity class, you use the @Id annotation on the

properties that make up your primary key. The primary-key class must meet these requirements :

o It must be serializable.o It must have a public no-arg constructor.o It must implement the equals( ) and hashCode( )

methods.(These methods are used when storing and when looking up objects.)

Example: o In this example we define a composite primary key

made up of last name and Social Security number for the Customer bean class.

CustomerPK.java 1 package entities; 2 import java.io.Serializable; 3 public class CustomerPK implements Serializable { 4 private String lastName; 5 private long ssn; 6 public CustomerPK(String lastName, long ssn) { 7 this.lastName = lastName; 8 this.ssn = ssn; 9 }10 public CustomerPK() {11 }12 public String getLastName() {13 return lastName;

Page 21: Ecom lec4 fall16_jpa

14 }15 public void setLastName(String lastName) {16 this.lastName = lastName;17 }18 public long getSsn() {19 return ssn;20 }21 public void setSsn(long ssn) {22 this.ssn = ssn;23 }24 @Override25 public boolean equals(Object obj) {26 if (obj == this) {27 return true;28 }29 if (!(obj instanceof CustomerPK)) {30 return false;31 }32 CustomerPK pk = (CustomerPK) obj;33 if (!lastName.equals(pk.lastName)) {34 return false;35 }36 if (ssn != pk.ssn) {37 return false;38 }39 return true;40 }41 @Override42 public int hashCode() {43 return lastName.hashCode() + (int) ssn;44 }45 }

Customer.java 1 package entities; 2 import java.io.Serializable; 3 import javax.persistence.Entity; 4 import javax.persistence.Id; 5 import javax.persistence.IdClass; 6 @Entity(name="cust") 7 @IdClass(CustomerPK.class) 8 public class Customer implements Serializable { 9 private static final long serialVersionUID = 1L;10 private String firstName;11 private String lastName;12 private long ssn;

Page 22: Ecom lec4 fall16_jpa

13 public String getFirstName() {14 return firstName;15 }16 public void setFirstName(String firstName) {17 this.firstName = firstName;18 }19 @Id20 public String getLastName() {21 return lastName;22 }23 public void setLastName(String lastName) {24 this.lastName = lastName;25 }26 @Id27 public long getSsn() {28 return ssn;29 }30 public void setSsn(long ssn) {31 this.ssn = ssn;32 }33 }

Note: Primary-key autogeneration is not supported for composite keys and primary-key classes. You will have to manually create the key values in code.@EmbeddedId A different way to define primary-key classes and

composite keys is to embed the primary-key class directly in the entity class.

The @javax.persistence.EmbeddedId annotation is used for this purpose in conjunction with the @javax.persistence.Embeddable annotation.

CustomerPK.java 1 package entities;

Page 23: Ecom lec4 fall16_jpa

2 3 import java.io.Serializable; 4 import javax.persistence.Column; 5 import javax.persistence.Embeddable; 6 7 @Embeddable 8 public class CustomerPK implements java.io.Serializable { 9 private String lastName;10 private long ssn;11 public CustomerPK() {12 }13 public CustomerPK(String lastName, long ssn) {14 this.lastName = lastName;15 this.ssn = ssn;16 }17 @Column(name = "CUSTOMER_LAST_NAME")18 public String getLastName() {19 return this.lastName;20 }21 public void setLastName(String lastName) {22 this.lastName = lastName;23 }24 @Column(name = "CUSTOMER_SSN")25 public long getSsn() {26 return ssn;27 }28 public void setSsn(long ssn) {29 this.ssn = ssn;30 }31 public boolean equals(Object obj) {32 if (obj == this) {33 return true;34 }35 if (!(obj instanceof CustomerPK)) {36 return false;37 }38 CustomerPK pk = (CustomerPK) obj;39 if (!lastName.equals(pk.lastName)) {40 return false;41 }42 if (ssn != pk.ssn) {43 return false;44 }45 return true;46 }47 48 public int hashCode() {

Page 24: Ecom lec4 fall16_jpa

49 return lastName.hashCode() + (int) ssn;50 }51 }

Customer.java

1 package entities; 2 import java.io.Serializable; 3 import javax.persistence.EmbeddedId; 4 import javax.persistence.Entity; 5 6 @Entity(name="cust1") 7 public class Customer implements java.io.Serializable { 8 private String firstName; 9 private CustomerPK pk;10 11 public String getFirstName( ) { return firstName; }12 public void setFirstName(String firstName) { this.firstName = firstName; }13 14 @EmbeddedId15 public CustomerPK getPk( ) { return pk; }16 public void setPk(CustomerPK pk) { this.pk = pk; }17 }

Page 25: Ecom lec4 fall16_jpa

Entity InheritanceSuppose we have this class hierarchy:

The Java Persistence specification provides three different ways to map an inheritance hierarchy to a relational database:

Single Table per Class Hierarchy

In the single table per class hierarchy mapping strategy, one database table represents every class of a given hierarchy. In our example, the Person, Customer, and Employee entities are represented in the same table.

The person entity:

Page 26: Ecom lec4 fall16_jpa

Person.java 1 package entities; 2 import java.io.Serializable; 3 import javax.persistence.DiscriminatorColumn; 4 import javax.persistence.DiscriminatorType; 5 import javax.persistence.DiscriminatorValue; 6 import javax.persistence.Entity; 7 import javax.persistence.GeneratedValue; 8 import javax.persistence.GenerationType; 9 import javax.persistence.Id;10 import javax.persistence.Inheritance;11 import javax.persistence.InheritanceType;12 13 @Entity14 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)15 @DiscriminatorColumn(name = "DISCRIMINATOR",16 discriminatorType = DiscriminatorType.STRING)17 @DiscriminatorValue("PERSON")18 public class Person implements Serializable {19 private static final long serialVersionUID = 1L;20 @Id21 @GeneratedValue(strategy = GenerationType.AUTO)22 private int id;23 private String firstName;24 private String lastName;25 public String getFirstName() {26 return firstName;27 }28 public void setFirstName(String firstName) {29 this.firstName = firstName;30 }31 public String getLastName() {32 return lastName;33 }34 public void setLastName(String lastName) {35 this.lastName = lastName;36 }37 public int getId() {38 return id;39 }40 public void setId(int id) {41 this.id = id;42 }43 }

Employee.java 1 package entities;

Page 27: Ecom lec4 fall16_jpa

2 3 import java.io.Serializable; 4 import javax.persistence.Entity; 5 6 @Entity 7 public class Employee extends Customer implements Serializable { 8 9 private static final long serialVersionUID = 1L;10 private int employeeId;11 12 public int getEmployeeId() {13 return employeeId;14 }15 16 public void setEmployeeId(int id) {17 employeeId = id;18 }19 }

C:\Projects_lecEntities\inheritance1\inheritance1-ejb\src\java\entities\Customer.java

1 package entities; 2 import java.io.Serializable; 3 import javax.persistence.Entity; 4 @Entity 5 public class Customer extends Person implements Serializable { 6 private static final long serialVersionUID = 1L; 7 private String street; 8 private String city; 9 private String zip;10 public String getCity() {11 return city;12 }13 public void setCity(String city) {14 this.city = city;15 }16 public String getStreet() {17 return street;18 }19 public void setStreet(String street) {20 this.street = street;21 }22 public String getZip() {23 return zip;24 }25 public void setZip(String zip) {26 this.zip = zip;

Page 28: Ecom lec4 fall16_jpa

27 }28 }

The Façade stateless session bean:C:\Projects_lecEntities\inheritance1\inheritance1-ejb\src\java\entities\

DataAccessBean.java

1 package entities; 2 import java.util.List; 3 import javax.ejb.Stateless; 4 import javax.persistence.EntityManager; 5 import javax.persistence.PersistenceContext; 6 7 @Stateless 8 public class DataAccessBean implements DataAccessBeanRemote { 9 @PersistenceContext10 private EntityManager manager;11 public void initializeDatabase() {12 Person p = new Person();13 p.setFirstName("Bill");14 p.setLastName("Burke");15 manager.persist(p);16 17 Customer cust = new Customer();18 cust.setFirstName("Sacha");19 cust.setLastName("Labourey");20 cust.setStreet("Se La Vie");21 cust.setCity("Neuchatel");22 cust.setZip("3332002-111");23 manager.persist(cust);24 25 Employee employee = new Employee();26 employee.setFirstName("Gavin");27 employee.setLastName("King");28 employee.setStreet("1st Street");29 employee.setCity("Atlanta");30 employee.setZip("33320");31 employee.setEmployeeId(15);32 manager.persist(employee);33 34 }35 36 public List findAllPersons() {37 return manager.createQuery("SELECT o FROM Person o").getResultList();38 }39 }

The client

Page 29: Ecom lec4 fall16_jpa

C:\Projects_lecEntities\ClientInheritance1\src\clientinheritance1\Main.java

1 package clientinheritance1; 2 import entities.*; 3 import java.util.List; 4 import javax.naming.Context; 5 import javax.naming.InitialContext; 6 import javax.naming.NamingException; 7 8 public class Main { 9 public static void main(String[] args) {10 try {11 Context context = new InitialContext();12 DataAccessBeanRemote dao = (DataAccessBeanRemote) context.lookup("java:global/inheritance1/inheritance1-ejb/DataAccessBean");13 dao.initializeDatabase();14 List persons = dao.findAllPersons();15 System.out.println("persons.size() = " + persons.size());16 for (Object obj : persons) {17 Person p = (Person) obj;18 System.out.println("\tclass is: " + p.getClass().getName());19 System.out.println("\tperson: " + p.getFirstName() + " "20 + p.getLastName());21 }22 23 } catch (NamingException e) {24 e.printStackTrace();25 }26 27 }28 }

Advantages1. The SINGLE_TABLE mapping strategy is the simplest to

implement, and there is only one table to administer and deal with.

2. The persistence engine does not have to do any complex

Page 30: Ecom lec4 fall16_jpa

joins, unions, when loading the entity, because all data is stored in one table.

Disadvantages1. One huge disadvantage of this approach is that all columns

of subclass properties must be nullable.

So, you cannot define NOT NULL constraints. 2. Because subclass property columns may be unused, the

SINGLE_TABLE strategy is not normalized.

Table per Concrete Class

In the table per concrete class strategy, a database table is defined for each concrete class in the hierarchy. This table has columns representing its properties, and all properties of any superclasses.

Page 31: Ecom lec4 fall16_jpa

The Person entity@Entity(name = "Person2")@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)public class Person implements Serializable {

private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String firstName; private String lastName;

public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; }}

The Person Table

Page 32: Ecom lec4 fall16_jpa

The Customer Table:

The Employee Table:

Advantages1. The advantage to this approach over the SINGLE_TABLE

strategy is that you can define not null constraints on subclass properties.

Disadvantages1. This strategy is not normalized, as it has redundant

columns in each of its tables for each of the base class's properties.

Table per Subclass

In the table per subclass mapping, each subclass has its own table, but this table contains only the properties that are defined on that particular class.

This strategy is also called the JOINED strategy because inorder to resolve all the properties for a sub class, a join between tables must be performed. The ID from the parent object is used as a foreign key to tables representing the subclass.

@Entity(name = "Person3")@Inheritance(strategy=InheritanceType.JOINED)public class Person implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String firstName; private String lastName; public String getFirstName() { return firstName;

Page 33: Ecom lec4 fall16_jpa

} public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; }}

@Statelesspublic class SessionBean implements SessionBeanRemote { @PersistenceContext private EntityManager manager; public void initializeDatabase() { Person p = new Person(); p.setFirstName("Bill"); p.setLastName("Burke"); manager.persist(p);

Costumer cust = new Costumer(); cust.setFirstName("Sacha"); cust.setLastName("Labourey"); cust.setStreet("Se La Vie"); cust.setCity("Neuchatel"); cust.setZip("3332002-111"); manager.persist(cust);

Employee employee = new Employee(); employee.setFirstName("Gavin"); employee.setLastName("King"); employee.setStreet("1st Street"); employee.setCity("Atlanta"); employee.setZip("33320"); employee.setEmployeeId(15); manager.persist(employee); } public List findAllPersons() { return manager.createQuery("SELECT o FROM Person3 o").getResultList(); }}

Page 34: Ecom lec4 fall16_jpa

Advantages The relational database model is completely normalized. Disadvantages It does not perform as well as the SINGLE_TABLE strategy.Example:

SELECT`EMPLOYEEID`,`FIRSTNAME` , `LASTNAME`, `ZIP`, `CITY`FROM mynewdatabase.employee3,mynewdatabase.person3, mynewdatabase.costumer3WHEREmynewdatabase.employee3.`ID`=mynewdatabase.costumer3.`ID` and mynewdatabase.costumer3.`ID`=mynewdatabase.person3.`ID`

Page 35: Ecom lec4 fall16_jpa

Entity Relationships يمكن أن يوجد( Relational Databaseفي قواعد البيانات العالئقية )

موجودة في الحياةارتباطات بين الجداول بهدف تمثيل مفاهيم بين الكائناتيمكن أن يعبر عن هذه االرتباطات JPA، في الواقعية

Entities من خالل الترميزات annotations. The Seven Relationship األنواع السبعة للعالقات بين الكائنات (

Types ( There are four types of cardinality:

1. One-to-one (Example: An Order and its Shipment address).2. One-to-many (Example: A Company and the Employees

working for this company).3. Many-to-one (Example: we have a series of Customers who

are each assigned to an Employee).4. Many-to-many (Example: Students and Courses).

In addition, each relationship can be either unidirectional or bidirectional.

(في االرتباط وحيد اإلتجاه كائن فقط يتضمن مؤشر إلى الكائن الثاني ، أما في االرتباط ثنائي اإلتجاه كل كائن يتضمن مؤشر للكائن

اآلخر.)

These options (cardinality and direction) seem to yield eight possibilities, but one-to-many and many-to-one bidirectional relationships are actually the same thing. Thus, there are only seven distinct relationship types.

Owning Side Any relationship has an owning side (طرف مالك). In a unidirectional relationship, because only one of the Entities in

the relationship bears reference to the other, that Entity is the owning side of the relationship. o In the example Order-Shipment, where the two tables are

illustrated in the figure the Order entity is the owning side.

Page 36: Ecom lec4 fall16_jpa

In the case of a bidirectional relationship, one of the entities is always the owning side and the other side is called the inverse side.

In One-to-Many and Many-to-One relationships, the Many part of the relationship is always the owning side.

One-to-One Unidirectional RelationshipExample: An example of a one-to-one unidirectional relationship is one

between an Order entity and a Shipment address.Relational database schema: In One-to-one unidirectional relationships, normally one table

contains a foreign key (pointer) to another table.

Page 37: Ecom lec4 fall16_jpa

Programming model: In unidirectional relationships (navigated only one way).

o One of the entities defines a property that lets it get or set the other entity in the relationship.

o Thus, inside the Order class, you can call the getShipment()/setShipment( ) methods to access the Shipment entity, but there are no methods inside the Shipment class to access the Order.

Let’s look at how we would mark up the Order entity class to implement this one-to-one relationship to Shipment:

OrderEntity.java

1 package ejb; 2 3 import java.io.Serializable; 4 import javax.persistence.CascadeType; 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.OneToOne; 9 @Entity10 public class OrderEntity implements Serializable {

Page 38: Ecom lec4 fall16_jpa

11 12 private int id;13 private String orderName;14 private Shipment shipment ; 15 16 public OrderEntity() {17 }18 @Id19 @GeneratedValue20 public int getId() {21 return id;22 }23 public void setId(int id) {24 this.id = id;25 }26 public String getOrderName() {27 return orderName;28 }29 public void setOrderName(String oname) {30 this.orderName = oname;31 }32 @OneToOne(cascade = CascadeType. PERSIST ) 33 public Shipment getShipment() {34 return shipment;35 }36 public void setShipment(Shipment shipment) {37 this.shipment = shipment;38 }39 }40

Cascading (التتالي) Cascading means that when you perform an entity manager

operation on an entity bean instance, you can automatically have

Page 39: Ecom lec4 fall16_jpa

the same operation performed on any relationship properties the entity may have.

For example, the entity manager can automatically create the Order and its related entity, all in one persist() method call:

Shipment s = new Shipment();s.setCity("Austin");s.setZipcode("78727");OrderEntity o = new OrderEntity();o.setOrderName("Software Order");o.setShipment(s);em.persist(o);

When to Use Cascading Be aware : You don’t always want to use cascading for every

relationship you have. o For example, you would not want to remove the related

Shipment address when removing an Order entity from the database.

مالحظة : We can use the annotation: @JoinColumn, to define the

column in the Order’s table that references the primary key of the Shipment table in the schema.

And If you are joining on something other than the primary-key column of the Shipment table, then you must use the referencedColumnName() attribute of @JoinColumn. This referencedColumnName() must be unique, since this is a one-to-one relationship.

Use the @JoinColumns annotation to define multiple foreign-key columns.

Page 40: Ecom lec4 fall16_jpa

But you do not need to specify metadata such as @JoinColumn if your persistence provider supports auto schema generation.

The Shipment entityC:\coursesFall2014\ecomFall2014\ecom_lec4_fall14\relationship\OnetoOneUni\OnetoOneUni-ejb\src\java\ejb\Shipment.java

1 package ejb; 2 import java.io.Serializable; 3 import javax.persistence.Entity; 4 import javax.persistence.GeneratedValue; 5 import javax.persistence.Id; 6 @Entity 7 public class Shipment implements Serializable { 8 private int id; 9 private String city;10 private String zipcode;11 12 public Shipment() {13 14 }15 @Id16 @GeneratedValue17 public int getId() {18 return id;19 }20 21 public void setId(int id) {22 this.id = id;23 }24 25 public String getCity() {26 return city;27 }28

Page 41: Ecom lec4 fall16_jpa

29 public void setCity(String city) {30 this.city = city;31 }32 33 public String getZipcode() {34 return zipcode;35 }36 37 public void setZipcode(String zipcode) {38 this.zipcode = zipcode;39 }40 }41

The Stateless OrderShipmentUniBean remote interface:C:\relationship\OnetoOneUni\OnetoOneUni-ejb\src\java\ejb\

OrderShipmentUniBeanRemote.java

1 package ejb; 2 import java.util.List; 3 import javax.ejb.Remote; 4 @Remote 5 public interface OrderShipmentUniBeanRemote { 6 public void doSomeStuff(); 7 public List getOrders(); 8 }

The Stateless OrderShipmentUniBean classC:\relationship\OnetoOneUni\OnetoOneUni-ejb\src\java\ejb\OrderShipmentUniBean.java

1 package ejb; 2 import java.util.List; 3 import javax.ejb.Stateless; 4 import javax.persistence.EntityManager; 5 import javax.persistence.PersistenceContext; 6 import javax.persistence.Query;

Page 42: Ecom lec4 fall16_jpa

7 import javax.persistence.criteria.Order; 8 9 @Stateless10 public class OrderShipmentUniBean implements OrderShipmentUniBeanRemote {11 @PersistenceContext12 EntityManager em;13 public void doSomeStuff() {14 Shipment s = new Shipment();15 s.setCity("Austin");16 s.setZipcode("78727");17 OrderEntity o = new OrderEntity();18 o.setOrderName("Software Order");19 o.setShipment(s);20 em.persist(o);21 }22 public List getOrders() {23 Query q = em.createQuery("SELECT o FROM OrderEntity o");24 return q.getResultList();25 }26 }27

The ClientC:\relationship\ClientOnetoOneUni\src\clientonetooneuni\Main.java

1 package clientonetooneuni; 2 3 import ejb.OrderShipmentUniBeanRemote; 4 import java.util.Iterator; 5 import java.util.List; 6 import javax.naming.Context; 7 import javax.naming.InitialContext; 8 import javax.naming.NamingException;

Page 43: Ecom lec4 fall16_jpa

9 10 public class Main {11 12 public static void main(String[] args) {13 try {14 Context context = new InitialContext();15 OrderShipmentUniBeanRemote os = (OrderShipmentUniBeanRemote) context.lookup("java:global/OnetoOneUni/OnetoOneUni-ejb/OrderShipmentUniBean");16 os.doSomeStuff();17 System.out.println("unidirectional one-to-one client");18 /*for (Object o : os.getOrders()) {19 ejb.OrderEntity order = (ejb.OrderEntity) o;20 System.out.println("Order " + order.getId() + ": " + order.getOrderName());21 System.out.println("\t Shipment details: " + order.getShipment().getCity() + " "22 + order.getShipment().getZipcode());23 }*/24 List results = os.getOrders();25 Iterator it = results.iterator();26 while (it.hasNext()) {27 ejb.OrderEntity order = (ejb.OrderEntity) it.next();28 System.out.println("Order " + order.getId() + ": " + order.getOrderName());29 System.out.println("\t Shipment details: " + order.getShipment().getCity() + " "30 + order.getShipment().getZipcode());31 }32 33 } catch (NamingException e) {34 e.printStackTrace();35 }

Page 44: Ecom lec4 fall16_jpa

36 37 }38 }39

Page 45: Ecom lec4 fall16_jpa

One-to-one bidirectional relationships To model the one to one bidirectional relationship between the

Order and Shipment entities, we need to declare a relationship property named order in the Shipment bean class.

If the relationship is bidirectional, the non-owning side must use the mappedBy element in the relationship annotation to specify the relationship field or property of the owning side.o In the (Order-shipment) example, we use the mappedBy()

attribute in @OneToOne relationship in the Shipment bean class, to specify Shipment entity as the inverse side of the relationship and the Order entity is the owning side of the relationship, and to specify the shipment property in the Order entity as the relationship field.

C:\relationship\OnetoOneBid\OnetoOneBid-ejb\src\java\ejb\OrderEntity.java

1 package ejb; 2 3 import java.io.Serializable; 4 import javax.persistence.CascadeType; 5 import javax.persistence.Entity; 6 import javax.persistence.Id; 7 import javax.persistence.OneToOne; 8 9 @Entity(name = "OrderBid")10 public class OrderEntity implements Serializable {11 12 private int id;13 private String orderName;14 private Shipment shipment;15 16 public OrderEntity() {17 id = (int) System.nanoTime();18 }

Page 46: Ecom lec4 fall16_jpa

19 20 @Id21 public int getId() {22 return id;23 }24 25 public void setId(int id) {26 this.id = id;27 }28 29 @OneToOne(cascade=CascadeType. PERSIST ) 30 public Shipment getShipment() {31 return shipment;32 }33 34 public void setShipment(Shipment shipment) {35 this.shipment = shipment;36 }37 38 public void setOrderName(String oname) {39 this.orderName = oname;40 }41 42 public String getOrderName() {43 return orderName;44 }45 }46

C:\relationship\OnetoOneBid\OnetoOneBid-ejb\src\java\ejb\Shipment.java

Page 47: Ecom lec4 fall16_jpa

1 package ejb; 2 3 import java.io.Serializable; 4 import javax.persistence.Entity; 5 import javax.persistence.Id; 6 import javax.persistence.OneToOne; 7 8 @Entity(name = "ShipmentBid") 9 public class Shipment implements Serializable {10 11 private int id;12 private String city;13 private OrderEntity order ; 14 private String zipcode;15 16 public Shipment() {17 id = (int) System.nanoTime();18 }19 20 @Id21 public int getId() {22 return id;23 }24 25 public String getCity() {26 return city;27 }28 29 public String getZipcode() {30 return zipcode;31 }32 33 public void setId(int id) {34 this.id = id;35 }

Page 48: Ecom lec4 fall16_jpa

36 37 public void setZipcode(String zipcode) {38 this.zipcode = zipcode;39 }40 41 public void setCity(String city) {42 this.city = city;43 }44 45 @OneToOne(mappedBy = "shipment" ) 46 public OrderEntity getOrder() {47 return this.order;48 }49 50 public void setOrder(OrderEntity order) {51 this.order = order;52 }53 }54

From the Façade classC:\coursesFall2014\ecomFall2014\ecom_lec4_fall14\relationship\OnetoOneBid\

OnetoOneBid-ejb\src\java\ejb\OrderShipmentBidBean.java

1 package ejb; 2 3 import java.util.List; 4 import javax.ejb.Stateless; 5 import javax.persistence.EntityManager; 6 import javax.persistence.PersistenceContext; 7 import javax.persistence.Query; 8 9 10 @Stateless11 public class OrderShipmentBidBean implements

Page 49: Ecom lec4 fall16_jpa

OrderShipmentBidBeanRemote {12 13 @PersistenceContext14 EntityManager em;15 16 public void doSomeStuff() {17 Shipment s = new Shipment();18 s.setCity("Austin");19 s.setZipcode("78727");20 OrderEntity o = new OrderEntity();21 o.setOrderName("Software Order");22 o.setShipment(s);23 s.setOrder(o);24 em.persist(o);25 }26 27 public List getShipments() {28 Query q = em.createQuery("SELECT s FROM ShipmentBid s");29 return q.getResultList();30 }31 }32

From the Client classC:\coursesFall2014\ecomFall2014\ecom_lec4_fall14\relationship\

ClientOnetoOneDid\src\clientonetoonebid\Main.java

1 package clientonetoonebid; 2 3 import ejb.OrderShipmentBidBeanRemote; 4 import ejb.Shipment; 5 import java.util.Iterator; 6 import java.util.List;

Page 50: Ecom lec4 fall16_jpa

7 import javax.naming.Context; 8 import javax.naming.InitialContext; 9 import javax.naming.NamingException;10 public class Main {11 12 public static void main(String[] args) {13 try {14 Context context = new InitialContext();15 OrderShipmentBidBeanRemote os = (OrderShipmentBidBeanRemote) context.lookup("java:global/OnetoOneBid/OnetoOneBid-ejb/OrderShipmentBidBean");16 /*17 os.doSomeStuff();18 System.out.println("Bidirectional one-to-one client");19 for (Object o : os.getShipments()) {20 Shipment sh = (Shipment) o;21 System.out.println("Shipment " + sh.getOrder().getOrderName());22 }*/23 os.doSomeStuff();24 List results = os.getShipments();25 Iterator it = results.iterator();26 while (it.hasNext()) {27 Shipment sh = (Shipment) it.next();28 System.out.println("Order " + sh.getId() + ": " + sh.getOrder().getOrderName());29 30 }31 32 } catch (NamingException e) {33 e.printStackTrace();34 }35 }

Page 51: Ecom lec4 fall16_jpa

36 }37

One-to-Many Unidirectional RelationshipExample: To illustrate a one-to-many unidirectional relationship let’s take an

example of a company and the employees working in this company.

Page 52: Ecom lec4 fall16_jpa

A unidirectional one-to-many relationship is usually mapped with a join table.

Programming model: The Company entity

C:\relationship\OnetoManyUni\OnetoManyUni-ejb\src\java\entities\Company.java

1 package entities; 2 3 import java.io.Serializable; 4 import java.util.Collection; 5 import javax.persistence.CascadeType; 6 import javax.persistence.Entity; 7 import javax.persistence.FetchType; 8 import javax.persistence.Id; 9 import javax.persistence.OneToMany;10 11 @Entity(name = "CompanyOMUni")12 public class Company implements Serializable {13 14 private static final long serialVersionUID = 1L;15 private int id;16 private String name;

Page 53: Ecom lec4 fall16_jpa

17 private Collection<Employee> employees;18 19 public Company() {20 id = (int) System.nanoTime();21 }22 23 @Id24 public int getId() {25 return id;26 }27 28 public void setId(int id) {29 this.id = id;30 }31 32 public String getName() {33 return name;34 }35 36 public void setName(String name) {37 this.name = name;38 }39 40 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)41 public Collection<Employee> getEmployees() {42 return employees;43 }44 45 public void setEmployees(Collection<Employee> employees) {46 this.employees = employees;47 }48 }49

Page 54: Ecom lec4 fall16_jpa

Fetch attribute, allows specifying whether a particular property is loaded lazily or eagerly when the persistent object is first fetched from the database.

Default LAZY.The Employee entity

C:\relationship\OnetoManyUni\OnetoManyUni-ejb\src\java\entities\Employee.java

1 2 package entities; 3 4 import java.io.Serializable; 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.GenerationType; 8 import javax.persistence.Id; 9 10 11 @Entity(name = "EmployeeOMUni")12 public class Employee implements Serializable {13 private static final long serialVersionUID = 1L;14 private int id;15 private String name;16 private char sex;17 18 public Employee() {19 id = (int) System.nanoTime();20 }21 @Id22 public int getId() {23 return id;24 }25 26 public void setId(int id) {

Page 55: Ecom lec4 fall16_jpa

27 this.id = id;28 }29 30 public String getName() {31 return name;32 }33 34 public void setName(String name) {35 this.name = name;36 }37 38 public char getSex() {39 return sex;40 }41 42 public void setSex(char sex) {43 this.sex = sex;44 }45 }46

The Stateless façadeC:\relationship\OnetoManyUni\OnetoManyUni-ejb\src\java\

entities\CompanyEmployeeOMUniBean.java

1 package entities; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.List; 6 import javax.ejb.Stateless; 7 import javax.persistence.EntityManager; 8 import javax.persistence.PersistenceContext; 9 import javax.persistence.Query;10

Page 56: Ecom lec4 fall16_jpa

11 12 @Stateless13 public class CompanyEmployeeOMUniBean implements CompanyEmployeeOMUniBeanRemote {14 15 @PersistenceContext16 EntityManager em;17 18 public void doSomeStuff() {19 Company c = new Company();20 c.setName("M*Power Internet Services, Inc.");21 22 Collection<Employee> employees = new ArrayList<Employee>();23 Employee e = new Employee();24 e.setName("Micah Silverman");25 e.setSex('M');26 employees.add(e);27 28 e = new Employee();29 e.setName("Tes Silverman");30 e.setSex('F');31 employees.add(e);32 33 c.setEmployees(employees);34 em.persist(c);35 36 c = new Company();37 c.setName("Sun Microsystems");38 39 employees = new ArrayList<Employee>();40 e = new Employee();41 e.setName("Rima Patel");42 e.setSex('F');43 employees.add(e);

Page 57: Ecom lec4 fall16_jpa

44 45 e = new Employee();46 e.setName("James Gosling");47 e.setSex('M');48 employees.add(e);49 50 c.setEmployees(employees);51 em.persist(c);52 53 }54 public List<Company> getCompanies() {55 Query q = em.createQuery("SELECT c FROM CompanyOMUni c");56 List<Company> lc = q.getResultList();57 return q.getResultList();58 }59 }60

The clientC:\relationship\ClientOnetoManyUni\src\clientonetomanyuni\

Main.java

1 package clientonetomanyuni; 2 3 import entities.Company; 4 import entities.CompanyEmployeeOMUniBeanRemote; 5 import entities.Employee; 6 import javax.naming.Context; 7 import javax.naming.InitialContext; 8 import javax.naming.NamingException; 9 10 11 public class Main {12

Page 58: Ecom lec4 fall16_jpa

13 /**14 * @param args the command line arguments15 */16 public static void main(String[] args) {17 18 19 try {20 Context context = new InitialContext();21 CompanyEmployeeOMUniBeanRemote os = (CompanyEmployeeOMUniBeanRemote) context.lookup("java:global/OnetoManyUni/OnetoManyUni-ejb/CompanyEmployeeOMUniBean");22 System.out.println("Unirectional one-to-many client");23 os.doSomeStuff();24 System.out.println("All Companies:");25 for (Object o : os.getCompanies()) {26 Company c = (Company) o;27 System.out.println("Here are the employees for company: " + c.getName());28 for (Employee e : c.getEmployees()) {29 System.out.println("\tName: " + e.getName() + ", Sex: " + e.getSex());30 }31 System.out.println();32 }33 } catch (NamingException e) {34 e.printStackTrace();35 }36 }37 }38

Page 59: Ecom lec4 fall16_jpa
Page 60: Ecom lec4 fall16_jpa

Many-to-One Unidirectional RelationshipExample: we have a set of Customers who are each assigned to an

Employee.Programming model Many-to-one relationships are described with the

@javax.persistence.ManyToOne The relationship between the Employee and Customer entities is

unidirectional, so the Employee bean class doesn’t define any relationship back to the Customer.

@Entitypublic class Customer{ ... /** * The primary {@link Employee} contact for this {@link Customer} */ @ManyToOne // Unidirectional private Employee primaryContact;...}

One-to-Many Bidirectional RelationshipExample:Company: Employees

C:\relationship\OnetoManyBid\OnetoManyBid-ejb\src\java\entities\Company.java

1 package entities;

Page 61: Ecom lec4 fall16_jpa

2 3 import java.io.Serializable; 4 import java.util.Collection; 5 import javax.persistence.CascadeType; 6 import javax.persistence.Entity; 7 import javax.persistence.FetchType; 8 import javax.persistence.Id; 9 import javax.persistence.OneToMany;10 11 @Entity(name="CompanyOMBi")12 public class Company implements Serializable {13 14 private static final long serialVersionUID = 1L;15 private int id;16 private String name;17 private Collection<Employee> employees;18 19 public Company() {20 id = (int) System.nanoTime();21 }22 23 @Id24 public int getId() {25 return id;26 }27 28 public void setId(int id) {29 this.id = id;30 }31 32 public String getName() {33 return name;34 }35 36 public void setName(String name) {

Page 62: Ecom lec4 fall16_jpa

37 this.name = name;38 }39 40 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "company")41 public Collection<Employee> getEmployees() {42 return employees;43 }44 45 public void setEmployees(Collection<Employee> employees) {46 this.employees = employees;47 }48 }49

C:\relationship\OnetoManyBid\OnetoManyBid-ejb\src\java\entities\Employee.java

1 package entities; 2 3 import java.io.Serializable; 4 import javax.persistence.Entity; 5 import javax.persistence.Id; 6 import javax.persistence.ManyToOne; 7 8 9 @Entity(name = "EmployeeOMBi")10 public class Employee implements Serializable {11 12 private static final long serialVersionUID = 1L;13 private int id;14 private String name;15 private char sex;16 private Company company;

Page 63: Ecom lec4 fall16_jpa

17 18 @ManyToOne19 public Company getCompany() {20 return company;21 }22 23 public void setCompany(Company company) {24 this.company = company;25 }26 27 public Employee() {28 id = (int) System.nanoTime();29 }30 31 @Id32 public int getId() {33 return id;34 }35 36 public void setId(int id) {37 this.id = id;38 }39 40 public String getName() {41 return name;42 }43 44 public void setName(String name) {45 this.name = name;46 }47 48 public char getSex() {49 return sex;50 }51

Page 64: Ecom lec4 fall16_jpa

52 public void setSex(char sex) {53 this.sex = sex;54 }55 }56 57

C:\relationship\OnetoManyBid\OnetoManyBid-ejb\src\java\entities\CompanyEmployeeOMBiBean.java

1 package entities; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.List; 6 import javax.ejb.Stateless; 7 import javax.persistence.EntityManager; 8 import javax.persistence.PersistenceContext; 9 import javax.persistence.Query;10 11 12 @Stateless13 public class CompanyEmployeeOMBiBean implements CompanyEmployeeOMBiBeanRemote {14 15 @PersistenceContext16 EntityManager em;17 18 @Override19 public void doSomeStuff() {20 Company c = new Company();21 c.setName("M*Power Internet Services, Inc.");22 23 Collection<Employee> employees = new

Page 65: Ecom lec4 fall16_jpa

ArrayList<Employee>();24 Employee e = new Employee();25 e.setName("Micah Silverman");26 e.setSex('M');27 e.setCompany(c);28 employees.add(e);29 30 e = new Employee();31 e.setName("Tes Silverman");32 e.setSex('F');33 e.setCompany(c);34 employees.add(e);35 36 c.setEmployees(employees);37 em.persist(c);38 39 c = new Company();40 c.setName("Sun Microsystems");41 42 employees = new ArrayList<Employee>();43 e = new Employee();44 e.setName("Rima Patel");45 e.setSex('F');46 e.setCompany(c);47 employees.add(e);48 49 e = new Employee();50 e.setName("James Gosling");51 e.setSex('M');52 e.setCompany(c);53 employees.add(e);54 55 c.setEmployees(employees);56 em.persist(c);57

Page 66: Ecom lec4 fall16_jpa

58 }59 60 @Override61 public List<Company> getCompanies() {62 Query q = em.createQuery("SELECT c FROM CompanyOMBi c");63 List<Company> lc = q.getResultList();64 return q.getResultList();65 }66 }67

C:\relationship\ClientOnetoManyBid\src\clientonetomanybid\Main.java

1 package clientonetomanybid; 2 3 import entities.Company; 4 import entities.CompanyEmployeeOMBiBeanRemote; 5 import entities.Employee; 6 import javax.naming.Context; 7 import javax.naming.InitialContext; 8 import javax.naming.NamingException; 9 10 11 public class Main {12 13 14 public static void main(String[] args) {15 16 try {17 Context context = new InitialContext();18 CompanyEmployeeOMBiBeanRemote os = (CompanyEmployeeOMBiBeanRemote)

Page 67: Ecom lec4 fall16_jpa

context.lookup("java:global/OnetoManyBid/OnetoManyBid-ejb/CompanyEmployeeOMBiBean");19 System.out.println("Birectional one-to-many client");20 os.doSomeStuff();21 System.out.println("All Companies:");22 for (Object o : os.getCompanies()) {23 Company c = (Company) o;24 System.out.println("Here are the employees for company: " + c.getName());25 for (Employee e : c.getEmployees()) {26 System.out.println("\tName: " + e.getName() + ", Sex: " + e.getSex() + ", Company" + e.getCompany().getName());27 }28 System.out.println();29 }30 } catch (NamingException e) {31 e.printStackTrace();32 }33 }34 }35

Page 68: Ecom lec4 fall16_jpa

Many-to-Many Bidirectional RelationshipExample: For example, in our example company every Employee may

belong to many Teams, and each Team may be composed of many Employees.

Usually, we use a join table to establish a many-to-many bidirectional relationship.

Programming model: Many-to-many relationships are logically defined using the

@javax.persistence.ManyToMany annotation: The Employee entity:@Entitypublic class Employee{.../**

Page 69: Ecom lec4 fall16_jpa

* The {@link Team}s to which this {@link Employee} belongs*/@ManyToMany(mappedBy = "members")private Collection<Team> teams;...} The Team entity:@Entitypublic class Team{.../*** {@link Employee}s on this {@link Task}.*/@ManyToManyprivate Collection<Employee> members;...} As with one-to-many bidirectional relationships, the mappedBy()

attribute identifies the property on the Team bean class that defines the relationship. This also identifies the Employee entity as the inverse side of the relationship and Team as owner.

Many-to-Many Unidirectional RelationshipExample: We may assign any number of Tasks to any number of Employees,

and Employees may be assigned to any number of Tasks. We’ll maintain a reference from Task to Employee, but not the other way around.

Programming model:To model this relationship, we need to add a collection-based relationship field for Employee to the Task:@Entitypublic class Task{...

Page 70: Ecom lec4 fall16_jpa

/*** {@link Employee} in charge of this {@link Task}*/@ManyToManyprivate Collection<Employee> owners;...}