• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ejb3 Dan Hinojosa
 

Ejb3 Dan Hinojosa

on

  • 1,694 views

ABQJUG Presentation on EJB3

ABQJUG Presentation on EJB3

Statistics

Views

Total Views
1,694
Views on SlideShare
1,688
Embed Views
6

Actions

Likes
1
Downloads
0
Comments
0

2 Embeds 6

https://www.linkedin.com 5
http://www.slideshare.net 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Ejb3 Dan Hinojosa Ejb3 Dan Hinojosa Presentation Transcript

    • EJB 3.0 Dan “Danno” Hinojosa
    • Why am I doing slides? Too much to cover So little time Slides are transportable, unlike code.
    • What was wrong with 2.1? People complained a lot about it, like Dwight XML Hell, large deployment descriptors Too many artifacts for one bean Lack of support for java.util.Date and java.util.Calendar Create your own subclass structure Create your own value object to represent an already developed entity bean.
    • Despair
    • What is new to EJB 3.0 POJO (Plain Old Java Objects) Development Annotations Based Descriptors Are Optional – Used to provide Database Metadata – Uses Dependency Injection Entities now based on proven Hibernate ideas
    • Session and MDB POJO & POJI (Plain Old Java Interfaces) Based Business Interface No Longer has to implement EJBObject or EJBLocalObject No more Home Interfaces Fully Annotation Based
    • YESSSSSSS!
    • Session and MDB (Continued) Field or method dependency injection. Using annotations (preferred) or through XML Lifecycle methods Custom methods for lifecycle events – Callback listeners maybe used for lifecycle – management Interceptors Used to intercept methods – Very AOP like –
    • EJB 2.1 Session Bean Interfaces public interface Cart extends EJBObject { public void add(String item) throws RemoteException; public void Collection getItems() throws RemoteException; public void process() throws RemoteException; } public interface CartHome extends EJBHome { public Cart create() throws CreateException, RemoteException; }
    • EJB 2.1 Session Bean Class public class CartEJB implements SessionBean { protected Collection items = new ArrayList(); public void add(String item) {items.add(item);} public Collection getItems() {return items;} public void completeOrder() {...} public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext context) {} }
    • EJB 2.1 Deployment Descriptor <session> <display-name>Cart</display-name> <ejb-name>Cart</ejb-name> <home>CartHome</home> <remote>Cart</remote> <ejb-class>CartEJB</ejb-class> <session-type>Stateful</session-type> <transaction-type>Container</transaction-type> </session> <assembly-descriptor> <container-transaction> .... </container-transaction> </assembly-descriptor>
    • So what's the big deal? Huge, too many interfaces Must do too much Too many interfaces – Must extend javax.ejb.Session – XML Hell Deployment Descriptor –
    • New EJB 3.0 Session Interface @Remote public interface Cart { public void add(String item); public Collection getItems(); public void process(); }
    • New EJB 3.0 Session Interface @Stateful public class CartBean implements Cart { private ArrayList items; public void add(String item) { items.add(item); } public Collection getItems() { return items; } @Remove public void process(); }
    • Dependency Injection Occurs when EJBContext is set Container figures what to set Can inject on a method or a field Can inject any resource like and EntityManager, MailSource, JDBC Sources, EJBContexts, etc. J2EE Scoped
    • Some Injection Examples @EJB BankService bankServiceBean; //field public void makeDeposit(float deposit) { bankServiceBean.deposit(deposit); } @Resource SessionContext ctx; //field TimerService service = ctx.getTimerService(); @Resource(name=”mySQLDB”) //method injection public void setDataSource(DataSource ds) { .... }
    • Callbacks and Interceptors Callbacks occur at a given lifecycle state or event Stateless Session Bean PostConstruct – PreDestroy – Stateful Session Bean Post Construct – PreDestroy – PrePassivate – PostActivate –
    • Callback Example @Stateful public class CartBean implements Cart { ArrayList items = new ArrayList(); @PostConstruct public void initCart() { items = items.clear(); } @PreDestroy @PrePassivate public logAsNoSale() { .... } }
    • Interceptors Offers AOP-like advice for beans Configured with annotations or XML Can be scoped to the class, method, or as a default
    • Interceptor Example Part 1 @Stateless @Interceptors(com.evolutionnext.Logger.class) public class HumanResourcesBean implements HumanResources { public void createEmployee(Employee employee); public void fireEmployee(Employee employee); public void adjustSalary(float raiseAmt); }
    • Interceptor Example Part 2 public class Logger { @AroundInvoke public Object doSomeLogging(InvocationContext inv) throws Exception { //logging here inv.proceed(); } }
    • Interceptor Example Part 3 @Stateless public class MyBean ... { public void notIntercepted() {} @Interceptors(org.acme.MyInterceptor.class) public void someMethod() { } @Interceptors(org.acme.MyInterceptor.class) public void anotherMethod() { } }
    • Interceptor Example 4 @Stateless @Interceptors(org.acme.AnotherInterceptor.class) public class MyBean ... { ... @ExcludeDefaultInterceptors @ExcludeClassInterceptors @Interceptors(org.acme.MyInterceptor.class) public void someMethod() { } }
    • Interceptors Using XML <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>INTERCEPTOR</interceptor-class> </interceptor-binding> <interceptor-binding> <ejb-name>EJBNAME</ejb-name> <interceptor-class>INTERCEPTOR</interceptor-class> </interceptor-binding> <interceptor-binding> <ejb-name>EJBNAME</ejb-name> <interceptor-class>INTERCEPTOR</interceptor-class> <method-name>METHOD</method-name> </interceptor-binding>
    • Interceptors Using XML 2 <interceptor-binding> <ejb-name>EJBNAME</ejb-name> <interceptor-class>INTERCEPTOR</interceptor-class> <method-name>METHOD</method-name> <method-params> <method-param>PARAM-1</method-param> <method-param>PARAM-2</method-param> ... <method-param>PARAM-n</method-param> </method-params> <interceptor-binding>
    • EJB Persistence API POJO Based Inheritance and Polymorphism O/R Mapping Complete Querying Capabilities Removed need for Data Value/Transfer Objects More testable
    • Some more advantages Concrete Classes No more interface hell Can be used OUTSIDE the Container Uses Collections for relations, no more CMR setup.
    • More? LifeCycle Cascading (PERSIST, REMOVE, REFRESH, MERGE, ALL) Extended Persistent Contexts available Default is scoped to one transaction – Extended is scoped over multiple transactions – FETCH JOINS are finally available
    • EntityManager public void persist(Object entity); public <T> T merge(T entity); public void remove(Object entity); public <T> T find(Class<T> entityClass, Object primaryKey); public void flush(); public void lock(Object entity, LockModeType lockMode); public void refresh(Object entity); public void clear(); public boolean contains(Object entity); public Query createQuery(String ejbqlString); public Query createNamedQuery(String name); public Query createNativeQuery(String sqlString);
    • Persisting @Stateless public class OrderEntryBean implements OrderEntry { @PersistenceContext EntityManager em; public Order enterOrder(Order newOrder) { Order order = em.persist(newOrder); } }
    • Find and Remove @Stateless public class OrderEntryBean implements OrderEntry { @PersistenceContext EntityManager em; public void removeOrder(Long id) { Order order = em.find(Order.class, id); em.remove(order); } }
    • Merging @Stateless public class OrderBean implements OrderI { @PersistenceContext EntityManager em; public Order updateOrder(Order newOrder) { Order order = em.merge(newOrder); return order; } }
    • Flush and Refresh @Stateless public class OrderBean implements OrderI { @PersistenceContext EntityManager em; public Order updateOrder(Order newOrder) { Order order = em.merge(newOrder); em.flush(); em.refresh(order); return order; } }
    • Flush and Refresh (Cont.) Persistence Engine may defer writing to the database until commit-time Flush forces the commit with underlying DB Refresh reloads the state of instance with the DB.
    • Extended Persistence Context Acts as an entity cache of managed instances when clients access the same component over multiple requests Spans multiple transactions Applies to: Stateful Session Beans – HttpSessions –
    • Transaction Scoped Example @Stateless public class ShoppingCartImpl implements ShoppingCart { @PersistenceContext EntityManager em; public Order getOrder(Long id) { return em.find(Order.class, id); } public Product getProduct(String name) { return (Product) em.createQuery(quot;select p from Product p where p.name = :namequot;) .setParameter(quot;namequot;, name) .getSingleResult(); } public LineItem createLineItem(Order order, Product product, int quantity) { LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); em.persist(li); return li; } }
    • XPC Example @Stateful @Transaction(REQUIRES_NEW) public class ShoppingCartImpl implements ShoppingCart { @PersistenceContext(type=EXTENDED) EntityManager em; private Order order; private Product product; public void initOrder(Long id) { order = em.find(Order.class, id); } public void initProduct(String name) { product = (Product) em.createQuery(quot;select p from Product p where p.name = :namequot;) .setParameter(quot;namequot;, name) .getSingleResult(); } public LineItem createLineItem(int quantity) { LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); return li; } }
    • Entity Callbacks PrePersist – when persist() is called PostPersist – after SQL Insert PreRemove – when remove() is called PostRemove – after SQL Delete PreUpdate – when container detects dirtyness PostUpdate – after SQL Update PostLoad – after instance was loaded All Attached using an @EntityListener annotation
    • Entity Callbacks Example @Entity @EntityListeners(com.acme.AlertMonitor.class) public class Account { ... @Id public Long getAccountId() { ... } public Integer getBalance() { ... } ... @Transient // because status depends upon non-persistent context public boolean isPreferred() { ... } public void deposit(Integer amount) { ... } public Integer withdraw(Integer amount) throws NSFException {... } @PrePersist protected void validateCreate() {...} @PostLoad protected void adjustPreferredStatus() {...} } public class AlertMonitor { @PostPersist public void newAccountAlert(Account acct) { Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBalance()); }
    • Primary Keys Can be denoted using @Id Example: @Id long myId; Use @EmbeddedId to indicate since id field from composite PK class Example @EmbeddedId MyObjID id; Also need to tell which Id class the composite key is @IdClass(MyObjID.class);
    • Fetch Hint to the Container to defer loading specific field or relationships of on object until they are accessed Defaults Simple, and Single Value Relationships – EAGER – Multi-value Relationships – LAZY – Entity should not access data directly from fields
    • Cascade Can cause specific lifecycle operation to cascade across relationships Can cascade combinations of PERSIST, MERGE, REMOVE, REFRESH, ALL – Default is for no cascading
    • Quick Cascade Example @OneToMany(cascade=ALL, mappedBy=”customer”) public Set getOrders() { return orders; }
    • Simple Mappings Direct Mappings of field to columns @Basic – known field type maps to standard DB – Column @Lob – maps to BLOB or CLOB type – @Column – you can customize the field and db column attributes here Default to type deemed appropriate by the container You can always override.
    • Example @Entity (access=FIELD) public class Customer { @Id int id; String name; int rating; @Lob Image photo; } @Entity (access=FIELD) public class Customer { @Id int id; String name; @Column(name=”Rating”) int rating; @Lob Image photo; }
    • Relationship Mappings Common relationships supported @ManyToOne, @OneToOne – single entity – @OneToMany, @ManyToMany – collection – Unidirectional and Bidirectional Owning and inverse sides to every relationship
    • One To One Example @OneToOne(cascade = {CascadeType.ALL}) @JoinColumn(name = quot;ADDRESS_IDquot;) public Address getAddress() { return address; }
    • Many To Many Example On the customer side: @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER, mappedBy=quot;customersquot;) Other side of the relationship in Flight. @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch =FetchType.EAGER) @JoinTable(table = @Table(name = quot;flight_customer_tablequot;), joinColumns = {@JoinColumn(name = quot;FLIGHT_IDquot;)}, inverseJoinColumns = {@JoinColumn(name = quot;CUSTOMER_IDquot;)}) public Set<Customer> getCustomers() { return customers; }
    • One To Many Example @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy=quot;orderquot;) public Collection<LineItem> getLineItems() { return lineItems; } @ManyToOne @JoinColumn(name = quot;order_idquot;) public Order getOrder() { return order; }
    • Embeddable Objects Example @Embeddable public class Name implements java.io.Serializable { }} The properties of Name must then be mapped to columns within Customer's table. @Embedded @AttributeOverrides({ @AttributeOverride(name = quot;firstquot;, column ={@Column(name = quot;FIRST_NAMEquot;)}), @AttributeOverride(name = quot;lastquot;, column = {@Column(name = quot;LAST_NAMEquot;)}) }) public Name getName() { return name; }
    • Inheritance Entities can extend Other entities – concrete or abstract – Non-entity classes – concrete or abstract – Three strategies Single Table – all classes in the same table – Joined – each class stored in a separate table – Table per Class – each concrete class stored in – separate table
    • What is the difference?
    • Single Table Example @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = quot;ANIMAL_TYPEquot;, discriminatorType = DiscriminatorType.STRING) public class Pet implements java.io.Serializable { @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING) @DiscriminatorValue(quot;DOGquot;) public class Dog extends Pet { public List findByWeight(double weight) { return manager.createQuery(quot;from Pet p where p.weight < :weightquot;).setParameter(quot;weightquot;, weight).getResultList(); }
    • Join Table Example @Entity @Inheritance(strategy = InheritanceType.JOINED) public class Pet implements java.io.Serializable { @Entity @Inheritance(strategy = InheritanceType.JOINED) public class Dog extends Pet { public List findByWeight(double weight) { return manager.createQuery(quot;from Pet p where p.weight < :weightquot;).setParameter(quot;weightquot;, weight).getResultList(); }
    • Table Per Class Example @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public class Pet implements java.io.Serializable { @Entity public class Dog extends Pet { public List findByWeight(double weight) { return manager.createQuery(quot;from Pet p where p.weight < :weightquot;).setParameter(quot;weightquot;, weight).getResultList(); }
    • Query API Definitely more solid! Date support Ability to return a single result or list Ability to fetch results. Ability to fetch set number of results Best of all: Queries return objects!
    • I could describe BNF syntax... select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] update_statement ::= update_clause [where_clause] delete_statement ::= delete_clause [where_clause] from_clause ::= FROM identification_variable_declaration {, {identification_variable_declaration | collection_member_declaration}}* identification_variable_declaration ::= range_variable_declaration { join | fetch_join }* range_variable_declaration ::= abstract_schema_name [AS] identification_variable join ::= join_spec join_association_path_expression [AS] identification_variable fetch_join ::= join_spec FETCH join_association_path_expression association_path_expression ::= collection_valued_path_expression | single_valued_association_path_expression join_spec::= [ LEFT [OUTER] | INNER ] JOIN join_association_path_expression ::= join_collection_valued_path_expression | join_single_valued_association_path_expression join_collection_valued_path_expression::= identification_variable.collection_valued_association_field join_single_valued_association_path_expression::= identification_variable.single_valued_association_field collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable
    • ..but no one likes BNF syntax Except for Dave Burkett Let do examples!
    • Simple Queries Retreive All Orders SELECT o FROM Order o Find all orders that need to be shipped to California: SELECT o FROM Order o WHERE o.shippingAddress.state = ‘CA’ Find all states for which there are orders: SELECT DISTINCT o.shippingAddress.state FROM Order o
    • Queries with Relationships Find all orders that have line items: SELECT DISTINCT o FROM Order o, IN(o.lineItems) l Note that the result of this query does not include orders with no associated line items. This query can also be written as: SELECT o FROM Order o WHERE o.lineItems IS NOT EMPTY Find all orders that have no line items: SELECT o FROM Order o WHERE o.lineItems IS EMPTY
    • More ! SELECT DISTINCT o FROM Order o JOIN o.lineItems l WHERE l.shipped = FALSE SELECT o FROM Order o WHERE NOT (o.shippingAddress.state = o.billingAddress.state AND o.shippingAddress.city = o.billingAddress.city AND o.shippingAddress.street = o.billingAddress.street) SELECT o FROM Order o WHERE o.shippingAddress <> o.billingAddress SELECT DISTINCT o FROM Order o JOIN o.lineItems l WHERE l.product.type = ‘book’ AND l.product.name = ‘Applying Enterprise JavaBeans: Component-Based Development for the J2EE Platform’
    • Now with input parameters SELECT DISTINCT o FROM Order o, IN(o.lineItems) l WHERE l.product.name = ?1 or SELECT DISTINCT o FROM Order o, IN(o.lineItems) l WHERE l.product.name = :name
    • So can I see a full example? public List findOrderByCustomer(Customer cust, int max) { return entityManager.createQuery ( “SELECT o from Order o “ + “where customer.id = :custId “ + “order by o.createdDateTime”) .setParameter(“custId”, cust.getId()) .setMaxResults(max) .getResultList(); ) }
    • Parting Words/Conclusion/Reflections EJB 3 = Totally Sweet
    • Questions? ????