2. Using the Tutorial Examples 3. Getting Started with Web Applications 5. JavaServer Pages Technology 7. JavaServer Pages Standard Tag Library 10. JavaServer Faces Technology 11. Using JavaServer Faces Technology in JSP Pages 12. Developing with JavaServer Faces Technology 13. Creating Custom UI Components 14. Configuring JavaServer Faces Applications 15. Internationalizing and Localizing Web Applications 16. Building Web Services with JAX-WS 17. Binding between XML Schema and Java Classes 19. SOAP with Attachments API for Java 21. Getting Started with Enterprise Beans 23. A Message-Driven Bean Example 24. Introduction to the Java Persistence API 25. Persistence in the Web Tier 26. Persistence in the EJB Tier Entity Relationships in theorder Application Self-Referential Relationships One-to-Many Relationship Mapped to Overlapping Primary and Foreign Keys Primary Keys in theorder Application Entity Mapped to More Than One Database Table Cascade Operations in theorder Application BLOB and CLOB Database Types in theorder Application Temporal Types in theorder Application Managing theorder Application's Entities Building and Running theorder Application Creating the Database Tables in NetBeans IDE Creating the Database Tables Using Ant Building, Packaging, Deploying, and Runningorder In NetBeans IDE Relationships in theroster Application The Many-To-Many Relationship inroster Entity Inheritance in theroster Application Automatic Table Generation in theroster Application Building and Running theroster Application Building, Packaging, Deploying, and Runningroster in NetBeans IDE Building, Packaging, Deploying, and Runningroster Using Ant 27. The Java Persistence Query Language 28. Introduction to Security in the Java EE Platform 29. Securing Java EE Applications 31. The Java Message Service API 32. Java EE Examples Using the JMS API 36. The Coffee Break Application | Theorder ApplicationTheorder application is a simple inventory and ordering application for maintaining acatalog of parts and placing an itemized order of those parts. It hasentities that represent parts, vendors, orders, and line items. These entities are accessedusing a stateful session bean that holds the business logic of the application.A simple command-line client adds data to the entities, manipulates the data, anddisplays data from the catalog. The information contained in an order can be divided into different elements. Whatis the order number? What parts are included in the order? What partsmake up that part? Who makes the part? What are the specifications forthe part? Are there any schematics for the part?order is a simplifiedversion of an ordering system that has all these elements. Theorder application consists of two modules:order-ejb, an enterprise bean JARfile containing the entities, the support classes, and a stateful session bean thataccesses the data in the entities; andorder-app-client, the application client that populates theentities with data and manipulates the data, displaying the results in a terminal. Entity Relationships in theorder ApplicationTheorder application demonstrates several types of entity relationships: one-to-many, many-to-one, one-to-one, unidirectional, andself-referential relationships. Self-Referential RelationshipsAself-referential relationship is a relationship between relationship fields in the same entity.Part has a fieldbomPart that has a one-to-many relationship with the fieldparts,which is also inPart. That is, a part can be made upof many parts, and each of those parts has exactly one bill-of-material part. The primary key forPart is a compound primary key, a combination ofthepartNumber andrevision fields. It is mapped to thePARTNUMBER andREVISIONcolumns in theEJB_ORDER_PART table. ...@ManyToOne@JoinColumns({ @JoinColumn(name="BOMPARTNUMBER", referencedColumnName="PARTNUMBER"), @JoinColumn(name="BOMREVISION", referencedColumnName="REVISION")})public Part getBomPart() { return bomPart;}...@OneToMany(mappedBy="bomPart")public Collection<Part> getParts() { return parts;}...One-to-One RelationshipsPart has a field,vendorPart, that has a one-to-one relationship withVendorPart’spartfield. That is, each part has exactly one vendor part, and vice versa. Here is the relationship mapping inPart: @OneToOne(mappedBy="part")public VendorPart getVendorPart() { return vendorPart;}Here is the relationship mapping inVendorPart: @OneToOne@JoinColumns({ @JoinColumn(name="PARTNUMBER", referencedColumnName="PARTNUMBER"), @JoinColumn(name="PARTREVISION", referencedColumnName="REVISION")})public Part getPart() { return part;}Note that, becausePart uses a compound primary key, the@JoinColumns annotation isused to map the columns in theEJB_ORDER_VENDOR_PART table to the columns inEJB_ORDER_PART.EJB_ORDER_VENDOR_PART’sPARTREVISION column refers toEJB_ORDER_PART’sREVISION column. One-to-Many Relationship Mapped to Overlapping Primary and Foreign KeysOrder has a field,lineItems, that has a one-to-many relationship withLineItem’s fieldorder.That is, each order has one or more line item. LineItem uses a compound primary key that is made up of theorderIdanditemId fields. This compound primary key maps to theORDERID andITEMIDcolumns in theEJB_ORDER_LINEITEM database table.ORDERID is a foreign key totheORDERID column in theEJB_ORDER_ORDER table. This means that theORDERID columnis mapped twice: once as a primary key field,orderId; and again asa relationship field,order. Here’s the relationship mapping inOrder: @OneToMany(cascade=ALL, mappedBy="order") public Collection<LineItem> getLineItems() { return lineItems;}Here is the relationship mapping inLineItem: @ManyToOne public Order getOrder() { return order;}Unidirectional RelationshipsLineItem has a field,vendorPart, that has a unidirectional many-to-one relationship withVendorPart. Thatis, there is no field in the target entity in this relationship. @ManyToOne public VendorPart getVendorPart() { return vendorPart;}Primary Keys in theorder ApplicationTheorder application uses several types of primary keys: single-valued primary keys, compoundprimary keys, and generated primary keys. Generated Primary KeysVendorPart uses a generated primary key value. That is, the application does notassign primary key values for the entities, but instead relies on the persistenceprovider to generate the primary key values. The@GeneratedValue annotation is used tospecify that an entity will use a generated primary key. InVendorPart, the following code specifies the settings for generating primary key values: @TableGenerator( name="vendorPartGen", table="EJB_ORDER_SEQUENCE_GENERATOR", pkColumnName="GEN_KEY", valueColumnName="GEN_VALUE", pkColumnValue="VENDOR_PART_ID", allocationSize=10)@Id@GeneratedValue(strategy=GenerationType.TABLE, generator="vendorPartGen")public Long getVendorPartNumber() { return vendorPartNumber;}The@TableGenerator annotation is used in conjunction with@GeneratedValue’sstrategy=TABLE element. That is, thestrategy used to generate the primary keys is use a table in thedatabase.@TableGenerator is used to configure the settings for the generator table. Thename element sets the name of the generator, which isvendorPartGen inVendorPart. TheEJB_ORDER_SEQUENCE_GENERATOR table, which has two columnsGEN_KEY andGEN_VALUE, will store the generatedprimary key values. This table could be used to generate other entity’s primarykeys, so thepkColumnValue element is set toVENDOR_PART_ID to distinguish this entity’s generatedprimary keys from other entity’s generated primary keys. TheallocationSize element specifiesthe amount to increment when allocating primary key values In this case, eachVendorPart’s primary key will increment by 10. The primary key fieldvendorPartNumber is of typeLong, as the generated primarykey’s field must be an integral type. Compound Primary KeysA compound primary key is made up of multiple fields and followsthe requirements described inPrimary Key Classes. To use a compound primary key, you must createa wrapper class. Inorder, two entities use compound primary keys:Part andLineItem. Part uses thePartKey wrapper class.Part’s primary key is a combination of thepart number and the revision number.PartKey encapsulates this primary key. LineItem uses theLineItemKey class.LineItem’s primary key is a combination ofthe order number and the item number.LineItemKey encapsulates this primary key. This istheLineItemKey compound primary key wrapper class: package order.entity;public final class LineItemKey implements java.io.Serializable { private Integer orderId; private int itemId; public int hashCode() { return ((this.getOrderId()==null ?0:this.getOrderId().hashCode()) ^ ((int) this.getItemId())); } public boolean equals(Object otherOb) { if (this == otherOb) { return true; } if (!(otherOb instanceof LineItemKey)) { return false; } LineItemKey other = (LineItemKey) otherOb; return ((this.getOrderId()==null ?other.orderId==null:this.getOrderId().equals (other.orderId)) && (this.getItemId == other.itemId)); } public String toString() { return "" + orderId + "-" + itemId; }}The@IdClass annotation is used to specify the primary key class in theentity class. InLineItem,@IdClass is used as follows: @IdClass(order.entity.LineItemKey.class)@Entity...public class LineItem {...}The two fields inLineItem are tagged with the@Id annotation tomark those fields as part of the compound primary key: @Idpublic int getItemId() { return itemId;}...@Id@Column(name="ORDERID", nullable=false, insertable=false, updatable=false)public Integer getOrderId() { return orderId;}FororderId, you also use the@Column annotation to specify the column namein the table, and that this column should not be inserted or updated,as it is an overlapping foreign key pointing at theEJB_ORDER_ORDER table’sORDERID column (seeOne-to-Many Relationship Mapped to Overlapping Primary and Foreign Keys). That is,orderId will be set by theOrder entity. InLineItem’s constructor, the line item number (LineItem.itemId) is set using theOrder.getNextIdmethod. public LineItem(Order order, int quantity, VendorPart vendorPart) { this.order = order; this.itemId = order.getNextId(); this.orderId = order.getOrderId(); this.quantity = quantity; this.vendorPart = vendorPart;}Order.getNextId counts the number of current line items, adds one, and returns thatnumber. public int getNextId() { return this.lineItems.size() + 1;}Part doesn’t require the@Column annotation on the two fields that comprisePart’scompound primary key. This is becausePart’s compound primary key is not an overlappingprimary key/foreign key. @IdClass(order.entity.PartKey.class)@Entity...public class Part {... @Id public String getPartNumber() { return partNumber; }... @Id public int getRevision() { return revision; }...}Entity Mapped to More Than One Database TablePart’s fields map to more than one database table:EJB_ORDER_PART andEJB_ORDER_PART_DETAIL. TheEJB_ORDER_PART_DETAILtable holds the specification and schematics for the part. The@SecondaryTable annotation is usedto specify the secondary table. ...@Entity@Table(name="EJB_ORDER_PART")@SecondaryTable(name="EJB_ORDER_PART_DETAIL", pkJoinColumns={ @PrimaryKeyJoinColumn(name="PARTNUMBER", referencedColumnName="PARTNUMBER"), @PrimaryKeyJoinColumn(name="REVISION", referencedColumnName="REVISION")})public class Part {...}EJB_ORDER_PART_DETAIL shares the same primary key values asEJB_ORDER_PART. ThepkJoinColumns element of@SecondaryTableis used to specify thatEJB_ORDER_PART_DETAIL’s primary key columns are foreign keystoEJB_ORDER_PART. The@PrimaryKeyJoinColumn annotation sets the primary key column names and specifieswhich column in the primary table the column refers to. In this case,the primary key column names for bothEJB_ORDER_PART_DETAIL andEJB_ORDER_PART are the same:PARTNUMBER andREVISION, respectively. Cascade Operations in theorder ApplicationEntities that have relationships to other entities often have dependencies on the existenceof the other entity in the relationship. For example, a line item ispart of an order, and if the order is deleted, then theline item should also be deleted. This is called a cascade delete relationship. Inorder, there are two cascade delete dependencies in the entity relationships. IftheOrder to which aLineItem is related is deleted, then theLineItemshould also be deleted. If theVendor to which aVendorPart is relatedis deleted, then theVendorPart should also be deleted. You specify the cascade operations for entity relationships by setting thecascade elementin the inverse (non-owning) side of the relationship. The cascade element is settoALL in the case ofOrder.lineItems. This means that all persistence operations (deletes,updates, and so on) are cascaded from orders to line items. Here is the relationship mapping inOrder: @OneToMany(cascade=ALL, mappedBy="order")public Collection<LineItem> getLineItems() { return lineItems;}Here is the relationship mapping inLineItem: @ManyToOne public Order getOrder() { return order;}BLOB and CLOB Database Types in theorder ApplicationThePARTDETAIL table in the database has a column,DRAWING, of typeBLOB.BLOB stands for binary large objects, which are used for storing binarydata such as an image. TheDRAWING column is mapped to the fieldPart.drawing of typejava.io.Serializable. The@Lob annotation is used to denote thatthe field is large object. @Column(table="EJB_ORDER_PART_DETAIL")@Lobpublic Serializable getDrawing() { return drawing;}PARTDETAIL also has a column,SPECIFICATION, of typeCLOB.CLOB stands for character largeobjects, which are used to store string data too large to bestored in aVARCHAR column.SPECIFICATION is mapped to the fieldPart.specification of typejava.lang.String. The@Lob annotation is also used here to denote that the fieldis a large object. @Column(table="EJB_ORDER_PART_DETAIL")@Lobpublic String getSpecification() { return specification;}Both of these fields use the@Column annotation and set thetable elementto the secondary table. Temporal Types in theorder ApplicationTheOrder.lastUpdate persistent property, which is of typejava.util.Date, is mapped to theEJB_ORDER_ORDER.LASTUPDATE database field, which is of the SQL typeTIMESTAMP. To ensure theproper mapping between these types, you must use the@Temporal annotation withthe proper temporal type specified in@Temporal’s element.@Temporal’s elements are of typejavax.persistence.TemporalType. The possible values are:
Here is the relevant section ofOrder: @Temporal(TIMESTAMP)public Date getLastUpdate() { return lastUpdate;}Managing theorder Application’s EntitiesTheRequestBean stateful session bean contains the business logic and manages the entitiesoforder. RequestBean uses the@PersistenceContext annotation to retrieve an entity manager instance which isused to manageorder’s entities inRequestBean’s business methods. @PersistenceContextprivate EntityManager em; ThisEntityManager instance is a container-managed entity manager, so the container takes careof all the transactions involved in the managingorder’s entities. Creating EntitiesTheRequestBean.createPart business method creates a newPart entity. TheEntityManager.persist method is usedto persist the newly created entity to the database. Part part = new Part(partNumber, revision, description, revisionDate, specification, drawing);em.persist(part); Finding EntitiesTheRequestBean.getOrderPrice business method returns the price of a given order, based ontheorderId. TheEntityManager.find method is used to retrieve the entity fromthe database. Order order = em.find(Order.class, orderId); The first argument ofEntityManager.find is the entity class, and the second isthe primary key. Setting Entity RelationshipsTheRequestBean.createVendorPart business method creates aVendorPart associated with a particularVendor. TheEntityManager.persist method is used to persist the newly createdVendorPart entity to the database,and theVendorPart.setVendor andVendor.setVendorPart methods are used to associate theVendorPartwith theVendor. PartKey pkey = new PartKey();pkey.partNumber = partNumber;pkey.revision = revision;Part part = em.find(Part.class, pkey);VendorPart vendorPart = new VendorPart(description, price, part);em.persist(vendorPart);Vendor vendor = em.find(Vendor.class, vendorId);vendor.addVendorPart(vendorPart);vendorPart.setVendor(vendor); Using QueriesTheRequestBean.adjustOrderDiscount business method updates the discount applied to all orders. It usesthefindAllOrders named query, defined inOrder: @NamedQuery( name="findAllOrders", query="SELECT o FROM Order o") TheEntityManager.createNamedQuery method is used to run the query. Because the query returnsaList of all the orders, theQuery.getResultList method is used. List orders = em.createNamedQuery( "findAllOrders") .getResultList(); TheRequestBean.getTotalPricePerVendor business method returns the total price of all the parts fora particular vendor. It uses a named parameter,id, defined in the namedqueryfindTotalVendorPartPricePerVendor defined inVendorPart. @NamedQuery( name="findTotalVendorPartPricePerVendor", query="SELECT SUM(vp.price) " + "FROM VendorPart vp " + "WHERE vp.vendor.vendorId = :id") When running the query, theQuery.setParameter method is used to set the namedparameterid to the value ofvendorId, the parameter toRequestBean.getTotalPricePerVendor. return (Double) em.createNamedQuery( "findTotalVendorPartPricePerVendor") .setParameter("id", vendorId) .getSingleResult();TheQuery.getSingleResult method is used for this query because the query returns asingle value. Removing EntitiesTheRequestBean.removeOrder business method deletes a given order from the database. It usestheEntityManager.remove method to delete the entity from the database. Order order = em.find(Order.class, orderId);em.remove(order); Building and Running theorder ApplicationThis section describes how to build, package, deploy, and run theorderapplication. To do this, you will create the database tables in the JavaDB server, then build, deploy, and run the example. Creating the Database Tables in NetBeans IDETo create the database tables in Java DB, the database server included withApplication Server, you need to create the database connection and execute the SQLcommands intut-install/examples/common/sql/javadb/tutorial.sql. Creating the Database ConnectionTo create the database connection do the following:
Creating the TablesTo create the tutorial tables, do the following:
Deleting the TablesTo delete the tutorial tables, do the following:
Creating the Database Tables Using AntThe database tables are automatically created by thecreate-tables task, which iscalled before you deploy the application with theant deploy task. To manuallycreate the tables, do the following:
Building, Packaging, Deploying, and Runningorder In NetBeans IDEFollow these instructions to build, package, deploy, and run theorder exampleto your Application Server instance using NetBeans IDE.
You will see the following output from the application client in the Outputtab: ...Cost of Bill of Material for PN SDFG-ERTY-BN Rev: 7: $241.86Cost of Order 1111: $664.68Cost of Order 4312: $2,011.44Adding 5% discountCost of Order 1111: $627.75Cost of Order 4312: $1,910.87Removing 7% discountCost of Order 1111: $679.45Cost of Order 4312: $2,011.44Average price of all parts: $117.55Total price of parts for Vendor 100: $501.06Ordered list of vendors for order 1111200 Gadget, Inc. Mrs. Smith100 WidgetCorp Mr. JonesCounting all line itemsFound 6 line itemsRemoving Order 4312Counting all line itemsFound 3 line itemsFound 1 out of 2 vendors with ’I’ in the name:Gadget, Inc.run-order-app-client:run-ant:run:BUILD SUCCESSFUL (total time: 22 seconds) Building, Packaging, Deploying, and Runningorder Using AntTo build the application components oforder, enter the following command: ant This runs thedefault task, which compiles the source files and packages theapplication into an EAR file located attut-install/examples/ejb/order/dist/order.ear. To deploy the EAR, make sure the Application Server is started, thenenter the following command: ant deploy Afterorder.ear is deployed, a client JAR,orderClient.jar, is retrieved. This containsthe application client. To run the application client, enter the following command: ant run You will see the following output: ...run: [echo] Running appclient for Order.appclient-command-common: [exec] Cost of Bill of Material for PN SDFG-ERTY-BN Rev: 7: $241.86 [exec] Cost of Order 1111: $664.68 [exec] Cost of Order 4312: $2,011.44 [exec] Adding 5% discount [exec] Cost of Order 1111: $627.75 [exec] Cost of Order 4312: $1,910.87 [exec] Removing 7% discount [exec] Cost of Order 1111: $679.45 [exec] Cost of Order 4312: $2,011.44 [exec] Average price of all parts: $117.55 [exec] Total price of parts for Vendor 100: $501.06 [exec] Ordered list of vendors for order 1111 [exec] 200 Gadget, Inc. Mrs. Smith [exec] 100 WidgetCorp Mr. Jones [exec] Counting all line items [exec] Found 6 line items [exec] Removing Order 4312 [exec] Counting all line items [exec] Found 3 line items [exec] Found 1 out of 2 vendors with ’I’ in the name: [exec] Gadget, Inc.BUILD SUCCESSFUL Note -Before re-running the application client, you must reset the database by running thecreate-tables task. Theall TaskAs a convenience, theall task will build, package, deploy, and run theapplication. To do this, enter the following command: ant all UndeployingorderTo undeployorder.ear, enter the following command: ant undeploy Copyright © 2010, Oracle and/or its affiliates. All rights reserved.Legal Notices |