Java EE – NetBeans generate different JPA code in “JPA controller from entity beans” and “JSF page from entity beans”

When using JPA entity beans in Java EE and web projects, there are two different JPA code generator wizards in NetBeans

The first wizard generates "JPA controller from entity beans" The second wizard generates "JSF page from entity bean", which creates the same appearance class as the controller in the first wizard, but uses alternative coding What is the difference between the facade class and the JPA controller?

The following is the appearance of the code generated by the first Wizard:

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();
        }
    }

}

This is from the second Wizard:

@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();
    }

}

This is a design problem Which is better? I prefer to use the second wizard and only implement the facade to reveal the functions of the JPA controller Is this the "right" way from a design point of view? Now, if they mean exactly the same, why does the JPA controller contain so much coding?

Solution

I don't use NetBeans, so I won't talk directly. I'm just diagnosing the generated code

"JPA controller from entity beans" generates Java se compatible Dao classes There is no container anywhere to manage dependency injection Create an entity manager manually and manage transactions manually These classes work well in "normal" Java se desktop applications and Java EE web applications

"JSF page from entity bean" generates Java EE compatible Dao class similar to stateless EJB The entity manager is injected by the container, and the transaction is managed completely transparently by the container (through the specification, a single stateless EJB method call is counted as a single complete transaction) They need to run Java EE containers and cannot be used in Java se desktop applications Because the Java EE container manages dependency injection and transactions transparently, this explains why they have much less code

Therefore, the JPA controller can also be used as is in Java EE web applications, but sooner or later you will encounter transactional problems Imagine that a single HTTP request (a single web form submission) is intended to perform multiple database operations through multiple of these classes in a specific order, and as long as one of the latter operations fails due to an exception, all content should be rolled back This will not work when you use the "JPA controller" method without refactoring a lot of code to create transactions externally, but it will be completely transparent in the way expected when using EJBs

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>