ecom lec4 fall16_jpa

Post on 27-Jan-2017

36 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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.

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

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:(غير مطلوب)

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

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:

Step 2:

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.

Step 4:Account.java

1 package entities; 2

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;

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

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

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();

43 }44 }45

Step 6:

Now we can see the generated Account table.

Step 7:The standalone client.

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:

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;

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:

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;

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;

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;

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() {

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 }

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:

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;

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;

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

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

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.

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

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;

} 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(); }}

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`

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.

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.

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 {

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

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.

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

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;

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;

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 }

36 37 }38 }39

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 }

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

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 }

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

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;

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 }

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.

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;

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

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) {

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

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);

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

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

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;

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) {

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;

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

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

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

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)

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

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{.../**

* 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{...

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

top related