Статьи

NetBeans в классе: перевод сгенерированного контроллера JPA NetBeans в контейнерную среду для GlassFish

Мастера создания новых файлов NetBeans значительно упрощают написание стандартного кода. Одним конкретным примером является создание классов контроллеров JPA из классов сущностей. Файл класса или файлы, написанные для вас, будут содержать все основные методы JPA для операций CRUD над имеющейся у вас сущностью или сущностями. Единственная небольшая проблема заключается в том, что этот класс написан для автономной среды, такой как то, что вы найдете в среде, которая не поддерживает внедрение зависимостей контекста. Чтобы использовать этот класс в среде GlassFish или другом контейнере, мы должны внести некоторые незначительные изменения.

При работе с GlassFish первым шагом является создание glassfish-resources.xml, а затем файла persistence.xml. Если база данных и ее таблицы еще не созданы, то сейчас самое время это сделать. Теперь создайте классы сущностей из базы данных , также показанные в диалоговом окне « Новый файл » ниже.

При всем этом на месте вы просто должны создать новый файл для проекта в категории Постоянство и тип файла из классов JPA контроллера из классов сущностей .

В следующем диалоговом окне вас спросят, для каких сущностей вы хотите иметь класс контроллера. Он должен показать вам сущности, которые вы создали для своего проекта. Они появятся в окне « Доступные классы сущностей», и вы будете использовать кнопки для перемещения тех, которые вам нужны. В моем примере есть только одна сущность, и я добавил ее в поле « Классы выбранных сущностей» .

На следующем шаге вы должны выбрать имя пакета для классов, которые будут созданы для вас. Вы можете использовать пакет, который уже существует.

Когда вы закончите, вы увидите созданный вами пакет с файлом с именем класса Entity, за которым следует JpaController.java. В моем примере это FishJpaController.java. Вы также найдете дополнительный пакет, который заканчивается исключениями, содержащими пользовательские классы исключений, которые предоставляют более информативные типы исключений.

Когда вы откроете файл, вы увидите класс, который был написан для вас.

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.