====== Javaee Layers ====== //Source: EBJ Design Pattern// * Presentation: JSF, JScript... * Application: UI workflow, Validation, Servlet, Userbean.. * Service: biz logic (EJB Session Bean) * Domain: domain logic, EntityBeans. * Persistence: DB, ORM. ====== Dev process ====== - Domain - Persistence - Service - Client --> last. ====== Packaging Server ====== === Data (Persistence layer) === DAO, SLSB === Controller (Application) === Backing Beans for JSFview. === Model (domain layer) === JPA Models, Entity Beans. === Service === EJB Beans. === Util-qualifier (Persistence) === Specifies Injection points for the EM. ====== Packaging Client ====== === View (Presentation) === === Rest (WS) === ==================================================================== ====== Preparing data Model====== * Design Entity Relationship using Dia... * Use workbench to generate Model and SQL Schemas. * ====== Entities & Session Facade ====== ===== Member Entity ===== package de.td.inhanoi.model; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import javax.validation.constraints.Digits; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; @Entity @XmlRootElement @Table(uniqueConstraints = @UniqueConstraint(columnNames = "email")) public class Member implements Serializable { /** Default value included to remove warning. Remove or modify at will. **/ private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; @NotNull @Size(min = 1, max = 25) @Pattern(regexp = "[A-Za-z ]*", message = "must contain only letters and spaces") private String name; @NotNull @NotEmpty @Email private String email; @NotNull @Size(min = 10, max = 12) @Digits(fraction = 0, integer = 12) @Column(name = "phone_number") private String phoneNumber; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } } ====== Managed Beans & JSF ====== package de.td.inhanoi.controller; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.ejb.Stateful; import javax.enterprise.event.Event; import javax.enterprise.inject.Model; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; import javax.persistence.EntityManager; import de.td.inhanoi.model.Member; // The @Stateful annotation eliminates the need for manual transaction demarcation @Stateful // The @Model stereotype is a convenience mechanism to make this a request-scoped bean that has an // EL name // Read more about the @Model stereotype in this FAQ: // http://sfwk.org/Documentation/WhatIsThePurposeOfTheModelAnnotation @Model public class MemberRegistration { @Inject private Logger log; @Inject private EntityManager em; @Inject private Event memberEventSrc; private Member newMember; @Produces @Named public Member getNewMember() { return newMember; } public void register() throws Exception { log.info("Registering " + newMember.getName()); em.persist(newMember); memberEventSrc.fire(newMember); initNewMember(); } @PostConstruct public void initNewMember() { newMember = new Member(); } } ====== Data Service ====== ===== MemberListProducer.java ===== package de.td.inhanoi.data; import de.td.inhanoi.model.Member; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Observes; import javax.enterprise.event.Reception; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; @RequestScoped public class MemberListProducer { @Inject private EntityManager em; private List members; // @Named provides access the return value via the EL variable name "members" in the UI (e.g., // Facelets or JSP view) @Produces @Named public List getMembers() { return members; } public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Member member) { retrieveAllMembersOrderedByName(); } @PostConstruct public void retrieveAllMembersOrderedByName() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery criteria = cb.createQuery(Member.class); Root member = criteria.from(Member.class); // Swap criteria statements if you would like to try out type-safe criteria queries, a new // feature in JPA 2.0 // criteria.select(member).orderBy(cb.asc(member.get(Member_.name))); criteria.select(member).orderBy(cb.asc(member.get("name"))); members = em.createQuery(criteria).getResultList(); } } ===== Util-Qualifier ===== package de.td.inhanoi.util; import java.util.logging.Logger; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; /** * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans * *

* Example injection on a managed bean field: *

* *
 * @Inject
 * private EntityManager em;
 * 
*/ public class Resources { // use @SuppressWarnings to tell IDE to ignore warnings about field not being referenced directly @SuppressWarnings("unused") @Produces @PersistenceContext private EntityManager em; @Produces public Logger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); } }
====== Books - Refs ====== http://www.amazon.com/dp/1430219548/?tag=stackoverfl08-20 http://www.coreservlets.com/ http://www.adam-bien.com/roller/abien/entry/simplest_possible_jsf_2_ejb