Full WebApplication JSF EJB JPA JAAS

71

Posted on January 2, 2012 by

Share it now!

Business – DAOs

I will use a generic DAO to basic CRUD operations and others two DAOs: one for User and another for Dog. It will be very easy to understand its use:

package com.dao;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

public abstract class GenericDAO<T> {
	private final static String UNIT_NAME = "CrudPU";

	@PersistenceContext(unitName = UNIT_NAME)
	private EntityManager em;

	private Class<T> entityClass;

	public GenericDAO(Class<T> entityClass) {
		this.entityClass = entityClass;
	}

	public void save(T entity) {
		em.persist(entity);
	}

	protected void delete(Object id, Class<T> classe) {
		T entityToBeRemoved = em.getReference(classe, id);

		em.remove(entityToBeRemoved);
	}

	public T update(T entity) {
		return em.merge(entity);
	}

	public T find(int entityID) {
		return em.find(entityClass, entityID);
	}

	// Using the unchecked because JPA does not have a
	// em.getCriteriaBuilder().createQuery()<T> method
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> findAll() {
		CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
		cq.select(cq.from(entityClass));
		return em.createQuery(cq).getResultList();
	}

	// Using the unchecked because JPA does not have a
	// ery.getSingleResult()<T> method
	@SuppressWarnings("unchecked")
	protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
		T result = null;

		try {
			Query query = em.createNamedQuery(namedQuery);

			// Method that will populate parameters if they are passed not null and empty
			if (parameters != null && !parameters.isEmpty()) {
				populateQueryParameters(query, parameters);
			}

			result = (T) query.getSingleResult();

		} catch (Exception e) {
			System.out.println("Error while running query: " + e.getMessage());
			e.printStackTrace();
		}

		return result;
	}

	private void populateQueryParameters(Query query, Map<String, Object> parameters) {

		for (Entry<String, Object> entry : parameters.entrySet()) {
			query.setParameter(entry.getKey(), entry.getValue());
		}
	}
}
package com.dao;

import javax.ejb.Stateless;

import com.model.Dog;

@Stateless
public class DogDAO extends GenericDAO<Dog> {

	public DogDAO() {
		super(Dog.class);
	}
}
package com.dao;

import java.util.HashMap;
import java.util.Map;

import javax.ejb.Stateless;

import com.model.User;

@Stateless
public class UserDAO extends GenericDAO<User> {

	public UserDAO() {
		super(User.class);
	}

	public User findUserByEmail(String email){
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("email", email);		

		return super.findOneResult(User.FIND_BY_EMAIL, parameters);
	}
}

About the code above:

  • I hid some warnings because the JPA code does not “understand” generics yet.
  • The method “findOneResult” is with protected access just to prevent external access from other classes; this method requires logic to populate the parameters as we can see in the UserDAO.
  • The class GenericDAO has a complete CRUD methods plus a method that returns a single object given a NamedQuery.
  • The UserDAO class has a method (findUserByEmail) that belongs only to the class; but it has all CRUD methods by inheritance. With this pattern of DAOs we got a code more flexible.
  • The DogDAO has no method in it but only the CRUD methods; you could implement any method in the class without problem.
  • Instead using a method to “save” and other to “update” your objects you could use one method “entityManager.merge()”. You will have the same result but you will need to pay attention to the Cascade options.
  • I did not use Interfaces because EJB 3.1 allows us to have Stateless Local Session Beans without interface. If you are using an older EJB version you will need to implement an interface (how to Implement EJBs with interfaces we will see in this post, in the Façades page). I will not develop with interfaces my DAO/Model just to save space in this post. Remember: “Always program to an interface” (Design Pattern – Strategy).
  • If you use the JBoss 4.2 you could use the org.jboss.annotation.ejb.LocalBinding or org.jboss.annotation.ejb.RemoteBinding annotations; in this annotation you can write the name that will be mapped and referred by the EJB.

Response to Full WebApplication JSF EJB JPA JAAS

  1. Gaynusha

    Hi am working an a Distributed java application with EJB and JPA. Am able to insert into database however am not able to retrieve any thing from the database. And am unsuccessful working with object in the remote interface. My entity classes are saved in the EJB Module and my Class Library is saving my Remote Inteface. Moreover if am saving my entity class in the class Library am not able to deploy the EJB application. Can you please help me regarding this.

    Regards Gaynusha

    • uaihebert Post author

      Hello Gaynusha,

      I am sorry but I have no idea of what is happening.

      Maybe if you set your log entry do DEBUG level an error/warning will be displayed.

      Thanks for passing by.

  2. uddy

    Great tuto but I’ve this errors can you help me.

    Thanks.!!

    15:33:23,897 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA
    15:33:24,186 INFO [org.jboss.msc] JBoss MSC version 1.0.2.GA
    15:33:24,256 INFO [org.jboss.as] JBAS015899: JBoss AS 7.1.1.Final “Brontes” starting
    15:33:25,084 ERROR [org.jboss.as.server] JBAS015956: Caught exception during boot: org.jboss.as.controller.persistence.ConfigurationPersistenceException: JBAS014676: Failed to parse configuration
    at org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:141) [jboss-as-controller-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.server.ServerService.boot(ServerService.java:266) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.controller.AbstractControllerService$1.run(AbstractControllerService.java:155) [jboss-as-controller-7.1.1.Final.jar:7.1.1.Final]
    at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_26]
    Caused by: javax.xml.stream.XMLStreamException: com.ctc.wstx.exc.WstxParsingException: Duplicate attribute ‘use-java-context’.
    at [row,col {unknown-source}]: [105,154]
    at org.jboss.as.connector.subsystems.datasources.DataSourcesExtension$DataSourceSubsystemParser.readElement(DataSourcesExtension.java:784)
    at org.jboss.as.connector.subsystems.datasources.DataSourcesExtension$DataSourceSubsystemParser.readElement(DataSourcesExtension.java:333)
    at org.jboss.staxmapper.XMLMapperImpl.processNested(XMLMapperImpl.java:110) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.staxmapper.XMLExtendedStreamReaderImpl.handleAny(XMLExtendedStreamReaderImpl.java:69) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.as.server.parsing.StandaloneXml.parseServerProfile(StandaloneXml.java:894) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readServerElement_1_1(StandaloneXml.java:330) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readElement(StandaloneXml.java:127) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.server.parsing.StandaloneXml.readElement(StandaloneXml.java:100) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.staxmapper.XMLMapperImpl.processNested(XMLMapperImpl.java:110) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.staxmapper.XMLMapperImpl.parseDocument(XMLMapperImpl.java:69) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:133) [jboss-as-controller-7.1.1.Final.jar:7.1.1.Final]
    … 3 more
    Caused by: com.ctc.wstx.exc.WstxParsingException: Duplicate attribute ‘use-java-context’.
    at [row,col {unknown-source}]: [105,154]
    at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:464)
    at com.ctc.wstx.sr.AttributeCollector.throwDupAttr(AttributeCollector.java:1143)
    at com.ctc.wstx.sr.AttributeCollector.resolveNamespaces(AttributeCollector.java:997)
    at com.ctc.wstx.sr.InputElementStack.resolveAndValidateElement(InputElementStack.java:498)
    at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2942)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2802)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1050)
    at com.ctc.wstx.sr.BasicStreamReader.nextTag(BasicStreamReader.java:1125)
    at org.jboss.staxmapper.XMLExtendedStreamReaderImpl.nextTag(XMLExtendedStreamReaderImpl.java:152) [staxmapper-1.1.0.Final.jar:1.1.0.Final]
    at org.jboss.as.connector.subsystems.datasources.DsParser.parseDataSources(DsParser.java:185)
    at org.jboss.as.connector.subsystems.datasources.DsParser.parse(DsParser.java:165)
    at org.jboss.as.connector.subsystems.datasources.DataSourcesExtension$DataSourceSubsystemParser.readElement(DataSourcesExtension.java:776)
    … 13 more

    15:33:25,114 FATAL [org.jboss.as.server] JBAS015957: Server boot has failed in an unrecoverable manner; exiting. See previous messages for details.
    15:33:25,137 INFO [org.jboss.as] JBAS015950: JBoss AS 7.1.1.Final “Brontes” stopped in 14ms

    • uaihebert Post author

      Hello uddy,

      It looks like you edited a xml with an error. Check the edited xml.

      Thanks for passing by. I am sorry for the late response, I was very busy this last month.

  3. WarKar

    Hello,

    You’ve created great tutorial, but I have problem with the last step – deploy CrudEAR project. This is the console output:


    20:57:07,839 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC00001: Failed to start service jboss.deployment.subunit."CrudEAR.ear"."CrudJSF.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.subunit."CrudEAR.ear"."CrudJSF.war".INSTALL: Failed to process phase INSTALL of subdeployment "CrudJSF.war" of deployment "CrudEAR.ear"
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121) [jboss-as-server-7.0.2.Final.jar:7.0.2.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1824) [jboss-msc-1.0.1.GA.jar:1.0.1.GA]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1759) [jboss-msc-1.0.1.GA.jar:1.0.1.GA]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [:1.7.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [:1.7.0_45]
    at java.lang.Thread.run(Unknown Source) [:1.7.0_45]
    Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: No component found for type 'com.facade.UserFacade' with name null
    at org.jboss.as.ejb3.deployment.processors.EjbInjectionSource.getResourceValue(EjbInjectionSource.java:68)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.addJndiBinding(ModuleJndiBindingProcessor.java:200)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor$1.handle(ModuleJndiBindingProcessor.java:168)
    at org.jboss.as.ee.component.ClassDescriptionTraversal.run(ClassDescriptionTraversal.java:52)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.processClassConfigurations(ModuleJndiBindingProcessor.java:140)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:133)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115) [jboss-as-server-7.0.2.Final.jar:7.0.2.Final]
    ... 5 more

    Could you help me please, and explain what I did wrong?
    Kind regards,
    Karolina

  4. Pingback: Full Web App JSF – EJB – Hibernate Tutorial | snippetjournal

  5. Stefanie

    Hi,

    you’ve done a great job with this tutorial! It was a hell of a help for me starting with this topic!
    Nevertheless I found out that I had a problem with caching data:
    When creating a group and assining it to a user the information was stored in the database but not in cache. That results in wrong actions when trying to delete the group (it was not encountered that there is a user having this group). Restarting the application solved the problem as the cache was fresh but I wanted the cache to be refreshed as soon as I do any modifying action like insert, update or delete.

    Therefore I added the following code to my abstract class GenericDao (just used the update method – same has to be applied for save and delete method):

    @Override
    public E update(final E entity) {
    em.merge(entity);
    refresh(entity);
    return entity;
    }

    @Override
    public void refresh(E entity) {
    em.getEntityManagerFactory().getCache().evict(this.entityClass, entity);
    }

    What do you think about this solution? Maybe it is a help for anybody who is looking for the same problem I was :-)

    Greetings,
    Stefi

    • uaihebert Post author

      Stefanie, good morning.

      Thank you for the feedback.

      I cannot tell you if this is the best solution for the problem because I would need to understand every detail of what is going on.

      I appreciate your time in leaving the solution here to help others with the same kind of problem.

      Thank you!

  6. Ali

    Hello,

    Very nice tutorial! Thank You.
    I would ask as a beginner, I want to use Glassfish instead of JBoss. Is it possible and where must I make changes ?

    Regards,
    Ali

    • uaihebert Post author

      Hello Ali,

      Yes, you can use it with Glassfish but I do not have here the files that you should change.

      Sorry about that.

      Thanks for passing by and the support.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *