Entities | Dao | Service | Controller |
---|---|---|---|
BasicDao.java | BasicService.java | MainSampleViewBean.java | |
BasicDaoImp.java | BasicServiceImp.java | AjaxBean.java | |
OrderEntity.java | OrderDao.java | OrderService.java | TestBean.java |
OrderDaoImp.java | OrderServiceImp.java | TreeBean.java | |
OrderPartsEntity.java | OrderPartsDao.java | OrderPartsService.java | OrderPartsBean.java |
OrderPartsDaoImp.java | OrderPartsServiceImp.java | ||
PartEntity.java | PartDao.java | PartService.java | |
PartDaoImp.java | PartServiceImp.java | ||
As previously mentioned, the view will access the controller, which will access the service layer, which will access the dao, which will access the entity. The single responsibility principle states: "that every object should have a single responsibility." Using these design patterns, we can adhere to that principle. The entity represents our data object. The DAO defines the crud operations to use on that data object. The service defines the transactions to be used with the DAO. And the controller will handle the request response activities from the view.
To review the entities, see Entities - JPA 2.0.
Let us take a "simple" example. The AjaxBean uses the OrderService to verify that a name entered into the view is unique, and returns whether or not it is. To implement the AjaxBean, we need the following files: AjaxBean.java, OrderService.java, OrderServiceImp.java, BasicService.java, BasicServiceImp.java, OrderDao.java, OrderDaoImp.java, BasicDao.java, BasicDaoImp.java, OrderEntity.java, applicationContext.xml (previously discussed) and ServiceAndDaoBeans.xml (discussed in Spring Beans).
In this senario, we have used both xml file configuration and annotations. Because we extend JpaDaoSupport in the Dao, we needed a way to inject the entityManagerFactory, and it was easiest to do in the xml file. So we create the Dao and Service Beans in the xml file. Now we are free to inject them wherever needed via either xml or annotations.
A few things to note: These are stateless beans, so when we do our crud operations, we have to merge our entity into the persistence context since that entity is "detached". You see that demonstrated with the delete method in the dao.
In the dao and service classes, I have commented out the annotations since we are using the xml file. If we were using annotations, the dao would be a repository, and the serivce a service.
Beyond that, I will let the code speak for itself, as there is a bit much to walk through them line by line. Remember, the AjaxBean is interacting with the view. That is why you will see a validator, faces context, etc. I did not post the ajax jsf page; that was posted in Validation. To view the bean creation, see Project 2 - Spring Beans. Note: the ServiceAndDaoBeans.xml is called from applicationContext.xml.
AjaxBean.java
package com.sample.beans;
import com.sample.entities.OrderEntity;
import com.sample.services.OrderService;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.validator.ValidatorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
/**
* @author Thomas Dias
*/
@Controller
@Scope("request")
public class AjaxBean implements Serializable {
@Autowired(required=true)
OrderService orderService;
private boolean nameValid;
private String name;
private String otherName;
private int counter = 0;
private String msg = "Starting Message";
/** Creates a new instance of AjaxBean */
public AjaxBean() {
}
@PostConstruct
public void init() {
nameValid = false;
}
public boolean isNameValid() {
return nameValid;
}
public void setNameValid(boolean nameValid) {
this.nameValid = nameValid;
}
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value == null || value.toString().isEmpty()) {
FacesMessage message = new FacesMessage("A Unique Name Less Then 21 Characters Must Be Supplied");
setNameValid(false);
throw new ValidatorException(message);
}
OrderEntity orderEntity = orderService.findByName(value.toString());
if (orderEntity != null) {
FacesMessage message = new FacesMessage("Name is not unique.");
setNameValid(false);
throw new ValidatorException(message);
}
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OrderService getOrderService() {
return orderService;
}
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getOtherName() {
return otherName;
}
public void setOtherName(String otherName) {
this.otherName = otherName;
}
public void listener(ActionEvent event) {
msg = "Called Action Listener";
}
public String actionCall() {
msg = "Called Action method";
return null;
}
public String sendAlert() {
return "showMessage('Executed a bean that returned a JavaScript Command');";
}
}
OrderServiceImp.java
package com.sample.services;
import com.sample.dao.BasicDao;
import com.sample.dao.OrderDao;
import com.sample.dao.PartDao;
import com.sample.entities.OrderEntity;
import com.sample.entities.PartEntity;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Thomas Dias
*/
//@Service
public class OrderServiceImp extends BasicServiceImp<OrderEntity> implements OrderService {
// @Autowired(required = true)
private OrderDao dao;
private PartDao partDao;
@Override
public BasicDao getDao() {
return dao;
}
@Override
public void setDao(BasicDao dao) {
this.dao = (OrderDao) dao;
}
@Override
@Transactional(readOnly = true)
public OrderEntity getOrderEntity(OrderEntity orderEntity) {
return ((OrderDao) dao).getOrderEntity(orderEntity);
}
@Override
@Transactional(readOnly = true)
public OrderEntity findByName(String name) {
return ((OrderDao) dao).findByName(name);
}
@Override
public PartDao getPartDao() {
return partDao;
}
@Override
public void setPartDao(PartDao partDao) {
this.partDao = partDao;
}
@Override
public List<PartEntity> getAvailableParts(Long id) {
return partDao.getAvailableParts(id);
}
}
OrderService.java
package com.sample.services;
import com.sample.dao.OrderDao;
import com.sample.dao.PartDao;
import com.sample.entities.OrderEntity;
import com.sample.entities.PartEntity;
import java.util.List;
/**
* @author Thomas Dias
*/
public interface OrderService extends BasicService<OrderEntity>, OrderDao {
public PartDao getPartDao();
public void setPartDao(PartDao partDao);
public List<PartEntity> getAvailableParts(Long id);
}
BasicServiceImp.java
package com.sample.services;
import java.util.List;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Thomas Dias
*/
public abstract class BasicServiceImp<T> implements BasicService<T> {
@Override
@Transactional(readOnly = true)
public int count() {
return getDao().count();
}
@Override
@Transactional(readOnly = true)
public List<T> findAll() {
return getDao().findAll();
}
@Override
@Transactional(readOnly = true)
public T find(Long id) {
return (T) getDao().find(id);
}
@Override
@Transactional
public void create(T entity) {
getDao().create(entity);
}
@Override
@Transactional
public void delete(T entity) {
getDao().delete(entity);
}
@Override
@Transactional
public void edit(T entity) {
getDao().edit(entity);
}
@Override
@Transactional
public void remove(Long id) {
getDao().remove(id);
}
@Override
public JpaTemplate getJpaTemplate() {
return getDao().getJpaTemplate();
}
}
BasicService.javapackage com.sample.services;
import com.sample.dao.BasicDao;
/**
* @author Thomas Dias
*/
public interface BasicService<T> extends BasicDao<T> {
public BasicDao getDao();
public void setDao(BasicDao dao);
}
OrderDaoImp.java
package com.sample.dao;
import com.sample.entities.OrderEntity;
import com.sample.entities.OrderPartsEntity;
import com.sample.entities.PartEntity;
import java.util.ArrayList;
import java.util.List;
//@Repository
public class OrderDaoImp extends BasicDaoImp<OrderEntity> implements OrderDao {
public OrderDaoImp() {
super(OrderEntity.class);
}
private List<OrderEntity> createSampleData() {
List<OrderEntity> list = null;
Long numberParts = (Long) getJpaTemplate().find("select count(*) from PartEntity t").get(0);
if (numberParts == 0) {
PartEntity tower = new PartEntity("Tower", null);
PartEntity monitor = new PartEntity("Monitor", tower);
PartEntity printer = new PartEntity("Printer", tower);
PartEntity paper = new PartEntity("Paper", printer);
PartEntity entertain = new PartEntity("Entertainment Subsystem", tower);
PartEntity speakers = new PartEntity("Speakers", entertain);
PartEntity glasses3d = new PartEntity("3D Glasses", entertain);
PartEntity pad = new PartEntity("Game Pad", entertain);
PartEntity building = new PartEntity("Building", null);
PartEntity security = new PartEntity("Security", building);
PartEntity guards = new PartEntity("Guards", security);
PartEntity cameras = new PartEntity("Cameras", security);
PartEntity alarm = new PartEntity("Alarm", security);
PartEntity carpet = new PartEntity("Carpet", building);
getJpaTemplate().persist(tower);
getJpaTemplate().persist(building);
OrderEntity sampleOrder = new OrderEntity();
sampleOrder.setName("Sample Order1");
OrderPartsEntity orderPartsEntity = new OrderPartsEntity(sampleOrder, tower, null);
list = new ArrayList<OrderEntity>();
list.add(sampleOrder);
getJpaTemplate().persist(sampleOrder);
}
return list;
}
@Override
public List<OrderEntity> findAll() {
List<OrderEntity> list = super.findAll();
if (list.isEmpty()) {
list = createSampleData();
}
return list;
}
private void loadParts(OrderPartsEntity part) {
for (OrderPartsEntity subPart : part.getSubOrderParts()) {
loadParts(subPart);
}
}
@Override
public OrderEntity getOrderEntity(OrderEntity orderEntity) {
OrderEntity fullyLoadedOrderEntity = getJpaTemplate().merge(orderEntity);
for (OrderPartsEntity part : fullyLoadedOrderEntity.getOrderedParts()) {
loadParts(part);
}
return fullyLoadedOrderEntity;
}
/**
* retrieves an order entity with name = supplied name
* @param name of the entity to be retrieved
* @return null if no entity has name, or the first entity whose name is name, order being undefined
*/
@Override
public OrderEntity findByName(String name) {
List<OrderEntity> results = getJpaTemplate().find("select q from OrderEntity q where name=?1", name);
if (results.isEmpty()) {
return null;
}
return results.get(0);
}
}
OrderDao.java
package com.sample.dao;
import com.sample.entities.OrderEntity;
/**
* @author Thomas Dias
*/
public interface OrderDao extends BasicDao<OrderEntity> {
public OrderEntity getOrderEntity(OrderEntity orderEntity) ;
public OrderEntity findByName(String name);
}
BasicDaoImp.java
package com.sample.dao;
import java.io.IOException;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import org.springframework.orm.jpa.support.JpaDaoSupport;
/**
* @author Thomas Dias
*/
public abstract class BasicDaoImp<T> extends JpaDaoSupport implements BasicDao<T> {
private static final Logger logger = Logger.getLogger("AbstractFacade");
private Class<T> entityClass;
static {
try {
final FileHandler fh = new FileHandler("JSFDemoAPP.log");
fh.setFormatter(new SimpleFormatter());
logger.addHandler(fh);
} catch (IOException e) {
} catch (SecurityException e) {
}
}
public BasicDaoImp(Class<T> entityClass) {
this.entityClass = entityClass;
}
@Override
public void create(T entity) {
getJpaTemplate().persist(entity);
}
@Override
public void edit(T entity) {
logger.log(Level.FINE, "Saving {0}, {1} ", new Object[]{entity.getClass(), entity});
getJpaTemplate().merge(entity);
}
@Override
public void delete(T entity) {
logger.log(Level.FINE, "Delete {0}, {1} ", new Object[]{entity.getClass(), entity});
getJpaTemplate().remove(getJpaTemplate().merge(entity));
}
@Override
public void remove(Long id) {
if (id != null) {
T toRemove = find(id);
if (toRemove != null) {
getJpaTemplate().remove(toRemove);
}
}
}
@Override
public T find(Long id) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, "my warning : finding {0}", id.toString());
}
logger.log(Level.INFO, "my info : finding {0}", id);
logger.severe("my severe : finding ");
return getJpaTemplate().find(entityClass, id);
}
@Override
public List<T> findAll() {
EntityManager em = getJpaTemplate().getEntityManagerFactory().createEntityManager();
javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return em.createQuery(cq).getResultList();
}
@Override
public int count() {
CriteriaBuilder cb = getJpaTemplate().getEntityManagerFactory().createEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery cq = cb.createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(cb.count(rt));
Query q = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
BasicDao.java
package com.sample.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.orm.jpa.JpaTemplate;
/**
* @author Thomas Dias
*/
public interface BasicDao<T> extends Serializable {
public void create(T entity);
public void edit(T entity);
public void delete(T entity);
public void remove(Long id);
public T find(Long id);
public List<T> findAll();
public int count();
public JpaTemplate getJpaTemplate();
}
No comments:
Post a Comment