Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

NetBeans in the Classroom: Translating the NetBeans Generated JPA Controller to a Container Environment for GlassFish

DZone's Guide to

NetBeans in the Classroom: Translating the NetBeans Generated JPA Controller to a Container Environment for GlassFish

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

The NetBeans New File wizards greatly simplify writing boilerplate code. One specific instance is the creation of JPA Controller Classes from an Entity Classes. The class file, or files, written for you will contain all the basic methods of JPA for CRUD operations on the entity or entities that you have. The only small issue is that this class is written for a standalone environment such as what you would find in an environment that does not support Context Dependency Injection. To use this class in a GlassFish environment or other container we have to make some minor changes.

When working with GlassFish the first step is to create the glassfish-resources.xml and then the persistence.xml file. If the database and its tables have not been created yet then this is the time to do this. Now create the Entity Classes from Database, also shown in the New File dialog below.

With all this in place you simply have to create a New File for the project in the category Persistence and the File Type of JPA Controller Classes from Entity Classes.


The next dialog will ask you which entities you wish to have a controller class written for. It should show you the entities you have created for your project. They will appear in the Available Entity Classes box and you use the buttons to move the ones that you want. In my example there is just one entity and I have added it to the Selected Entities Classes box.


In the next step you must select the package name for the classes that will be created for you. You can use a package that already exists.


When you Finish you will see the package you created with a file that has the name of the Entity class followed by JpaController.java. In my example it is FishJpaController.java. You will also find an additional package that ends in exceptions that contains custom Exception classes that provide more informative exception types.


When you open the file you will see the class that has been written for you.

package com.kenfogel.beans;

import com.kenfogel.beans.exceptions.NonexistentEntityException;
import com.kenfogel.beans.exceptions.RollbackFailureException;
import com.kenfogel.entities.Fish;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;

/**
 *
 * @author Ken
 */
public class FishJpaController implements Serializable {

    public FishJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }

    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Fish fish) throws RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            em.persist(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Fish fish) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            fish = em.merge(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = fish.getId();
                if (findFish(id) == null) {
                    throw new NonexistentEntityException("The fish with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Fish fish;
            try {
                fish = em.getReference(Fish.class, id);
                fish.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The fish with id " + id + " no longer exists.", enfe);
            }
            em.remove(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Fish> findFishEntities() {
        return findFishEntities(true, -1, -1);
    }

    public List<Fish> findFishEntities(int maxResults, int firstResult) {
        return findFishEntities(false, maxResults, firstResult);
    }

    private List<Fish> findFishEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Fish.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Fish findFish(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Fish.class, id);
        } finally {
            em.close();
        }
    }

    public int getFishCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Fish> rt = cq.from(Fish.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}

The changes that you have to make are quite straightforward. First, we need to make this class a managed bean and change the EntityManager and UserTransaction into Injected classes.

@Named
@SessionScoped
public class FishJpaControllerUpdate implements Serializable {

    @Resource
    private UserTransaction utx;

    @PersistenceContext
    private EntityManager en;

NetBeans will help you in adding the necessary imports. The next step is to delete the constructor. As a managed bean you must have a default constructor. If you dislike not seeing a constructor in your class then you can add an empty one.

    /**
     * Default constructor
     */
    public FishJpaControllerUpdate() {
    }

Delete the method getEntityManager(). CDI will take care of creating the EntityManager for you.

The last step is to modify every method in the class that has as a first line:

EntityManager em = null;

We don’t need to call upon getEntityManager nor do we need to close the EntityManager when we are finished.

The create method:

public void create(Fish fish) throws RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            em.persist(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

Becomes:

    public void create(Fish fish) throws RollbackFailureException, Exception {
        try {
            utx.begin();
            em.persist(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        }
    }

The query method findFishEntities:

    private List<Fish> findFishEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Fish.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

Becomes:

    private List<Fish> findFishEntities(boolean all, int maxResults, int firstResult) {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Fish.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
    }

Clean up the rest of the methods and your controller will look like, with my added comments, the following:

package com.kenfogel.beans;

import com.kenfogel.beans.exceptions.NonexistentEntityException;
import com.kenfogel.beans.exceptions.RollbackFailureException;
import com.kenfogel.entities.Fish;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.persistence.PersistenceContext;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

/**
 *
 * @author kfogel
 */
@Named
@SessionScoped
public class FishJpaControllerUpdate implements Serializable {

    @Resource
    private UserTransaction utx;

    @PersistenceContext
    private EntityManager em;

    /**
     * Default constructor
     */
    public FishJpaControllerUpdate() {
    }

    /**
     * Take a new or detached entity and add it as a new record in the table
     * 
     * @param fish
     * @throws RollbackFailureException
     * @throws Exception 
     */
    public void create(Fish fish) throws RollbackFailureException, Exception {
        try {
            utx.begin();
            em.persist(fish);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        }
    }

    /**
     * Take a detached entity and update the matching record in the table
     * 
     * @param fish
     * @throws NonexistentEntityException
     * @throws RollbackFailureException
     * @throws Exception 
     */
    public void edit(Fish fish) throws NonexistentEntityException, RollbackFailureException, Exception {
        try {
            utx.begin();
            fish = em.merge(fish);
            utx.commit();
        } catch (NotSupportedException | SystemException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException ex) {
            try {
                utx.rollback();
            } catch (IllegalStateException | SecurityException | SystemException re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = fish.getId();
                if (findFish(id) == null) {
                    throw new NonexistentEntityException("The fish with id " + id + " no longer exists.");
                }
            }
            throw ex;
        }
    }

    /**
     * Delete the record that matched the primary key. Verify that the record exists before deleting it.
     * 
     * @param id
     * @throws NonexistentEntityException
     * @throws RollbackFailureException
     * @throws Exception 
     */
    public void destroy(Integer id) throws NonexistentEntityException, RollbackFailureException, Exception {
        try {
            utx.begin();
            Fish fish;
            try {
                fish = em.getReference(Fish.class, id);
                fish.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The fish with id " + id + " no longer exists.", enfe);
            }
            em.remove(fish);
            utx.commit();
        } catch (NotSupportedException | SystemException | NonexistentEntityException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException ex) {
            try {
                utx.rollback();
            } catch (IllegalStateException | SecurityException | SystemException re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        }
    }

    /**
     * Return all the records in the table
     * 
     * @return 
     */
    public List<Fish> findFishEntities() {
        return findFishEntities(true, -1, -1);
    }

    /**
     * Return some of the records from the table. Useful for paginating.
     * 
     * @param maxResults
     * @param firstResult
     * @return 
     */
    public List<Fish> findFishEntities(int maxResults, int firstResult) {
        return findFishEntities(false, maxResults, firstResult);
    }

    /**
     * Either find all or find a group of fish
     * 
     * @param all True means find all, false means find subset
     * @param maxResults Number of records to find
     * @param firstResult Record number to start returning records
     * @return 
     */
    private List<Fish> findFishEntities(boolean all, int maxResults, int firstResult) {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Fish.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
    }

    /**
     * Find a record by primary key
     * 
     * @param id
     * @return 
     */
    public Fish findFish(Integer id) {
            return em.find(Fish.class, id);
    }

    /**
     * Return the number of records in the table
     * 
     * @return 
     */
    public int getFishCount() {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Fish> rt = cq.from(Fish.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            System.out.println("fish count: " + ((Long) q.getSingleResult()).intValue());
            return ((Long) q.getSingleResult()).intValue();
    }

}

You are now ready to use this controller class in your JPA/CDI project.

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}