Netbeans在“来自实体bean的JPA控制器”和“来自实体bean的JSF页面”中生成不同的JPA代码

时间:2011-07-11 09:54:16

标签: java-ee jsf-2 netbeans-6.9

在Java EE和Web项目中使用JPA实体bean时,Netbeans中有两个不同的JPA代码生成器向导。

第一个向导生成“来自enetity beans的JPA控制器”。第二个向导生成“来自实体bean的JSF页面”,它创建的外观类与第一个向导中的控制器完全相同,但使用备用编码。外观类和JPA控制器之间有什么区别?

以下是第一个向导生成的代码的样子:

 public class UserimagesJpaController {

    public UserimagesJpaController() {
        emf = Persistence.createEntityManagerFactory("ArticlesWeb-ejbPU");
    }
    private EntityManagerFactory emf = null;

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

    public void create(Userimages userimages) throws PreexistingEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Users users = userimages.getUsers();
            if (users != null) {
                users = em.getReference(users.getClass(), users.getIdUsers());
                userimages.setUsers(users);
            }
            em.persist(userimages);
            if (users != null) {
                users.getUserimagesList().add(userimages);
                users = em.merge(users);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findUserimages(userimages.getIdUserImages()) != null) {
                throw new PreexistingEntityException("Userimages " + userimages + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Userimages userimages) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Userimages persistentUserimages = em.find(Userimages.class, userimages.getIdUserImages());
            Users usersOld = persistentUserimages.getUsers();
            Users usersNew = userimages.getUsers();
            if (usersNew != null) {
                usersNew = em.getReference(usersNew.getClass(), usersNew.getIdUsers());
                userimages.setUsers(usersNew);
            }
            userimages = em.merge(userimages);
            if (usersOld != null && !usersOld.equals(usersNew)) {
                usersOld.getUserimagesList().remove(userimages);
                usersOld = em.merge(usersOld);
            }
            if (usersNew != null && !usersNew.equals(usersOld)) {
                usersNew.getUserimagesList().add(userimages);
                usersNew = em.merge(usersNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = userimages.getIdUserImages();
                if (findUserimages(id) == null) {
                    throw new NonexistentEntityException("The userimages with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Userimages userimages;
            try {
                userimages = em.getReference(Userimages.class, id);
                userimages.getIdUserImages();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The userimages with id " + id + " no longer exists.", enfe);
            }
            Users users = userimages.getUsers();
            if (users != null) {
                users.getUserimagesList().remove(userimages);
                users = em.merge(users);
            }
            em.remove(userimages);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Userimages> findUserimagesEntities() {
        return findUserimagesEntities(true, -1, -1);
    }

    public List<Userimages> findUserimagesEntities(int maxResults, int firstResult) {
        return findUserimagesEntities(false, maxResults, firstResult);
    }

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

    public Userimages findUserimages(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Userimages.class, id);
        } finally {
            em.close();
        }
    }

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

}

这是来自第二个向导:

 @Stateless
 public class UserimagesFacade extends AbstractFacade<Userimages> {
    @PersistenceContext(unitName = "ArticlesWeb-ejbPU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public UserimagesFacade() {
        super(Userimages.class);
    }

 }

public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

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

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

}

这是一个设计问题。哪个更好?我更喜欢使用第二个向导并仅实现Facade以揭示JPA控制器的功能。这是从设计角度来看的“正确”方式吗?现在,如果它们的含义完全相同,为什么JPA控制器包含如此多的编码?

1 个答案:

答案 0 :(得分:7)

我不使用Netbeans,所以我不会直接说话,我只是在诊断生成的代码。

“来自enetity beans的JPA控制器”生成Java SE兼容的DAO类。任何地方都没有容器管理依赖注入的方法。手动创建实体管理器并手动管理事务。这些类在“普通的”Java SE桌面应用程序和Java EE Web应用程序中都可以正常工作。

“来自实体bean的JSF页面”生成了与无状态EJB相似的Java EE兼容DAO类。实体管理器由容器注入,并且事务由容器完全透明地管理(通过规范,单个无状态EJB方法调用计为单个完整事务)。它们需要运行Java EE容器,并且不能在Java SE桌面应用程序中使用它们。由于Java EE容器透明地管理依赖注入和事务,这解释了为什么它们的代码少得多。

因此,“JPA控制器”也可以在Java EE Web应用程序中原样使用,但您迟早可能会遇到事务性问题。想象一下,单个HTTP请求(单个Web表单提交)意图以特定顺序通过多个这些类执行多个DB操作,并且只要后一个操作之一失败,就应该回滚所有除了。当您使用“JPA Controller”方法而不重构大量代码以便在外部创建事务时,这将无法工作,但这将完全透明地使用您在使用EJB时​​的预期方式。