java-ee – Netbeans在“来自enetity beans的JPA控制器”和“来
在
Java EE和Web项目中使用JPA实体bean时,Netbeans中有两个不同的JPA代码生成器向导.
第一个向导生成“来自enetity beans的JPA控制器”.第二个向导生成“来自实体bean的JSF页面”,它创建的外观类与第一个向导中的控制器完全相同,但使用备用编码. Facade类和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控制器包含如此多的编码? 解决方法
我不使用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表单提交)旨在以特定顺序通过多个这些类执行多个数据库操作,并且只要后一个操作之一因异常而失败,就应该回滚所有内容.当您使用“JPA Controller”方法而不重构大量代码以便在外部创建事务时,这将无法工作,但这将完全透明地使用EJB时??的预期方式. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |