EJB 3.1通用DAO

4

我正在尝试实现一个通用的DAO以在我的项目中使用。到目前为止,我已经实现的代码如下:

基础DAO

public abstract class BaseDAO<T> {

    private Class<T> entityClass;

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

    protected abstract EntityManager getEntityManager();

    public T persist(T entity) {
        getEntityManager().persist(entity);
        return entity;
    }

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

    public T remove(T entity) {
        getEntityManager().remove(entity);
        return entity;
    }

    public List<T> findAll() {

    Query q = getEntityManager().createQuery("SELECT e FROM " + entityClass.getName()
                + " e");
        List<T> list = (List<T>) q.getResultList();
        return list;
    }

    public T find(Long id) {
        T e = getEntityManager().find(entityClass, id);
        return e;
    }

}

Extended DAO

@Stateless
public class CustomerDAO extends BaseDAO<Customer> {

    @PersistenceContext(unitName="customerPersistenceUnit")
    private EntityManager em;

    public CustomerDAO(Class<Customer> entityClass) {
            super(entityClass);
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

}

控制器类

@ManagedBean
@RequestScoped
public class CustomerController {

    @EJB
    private CustomerDAO customerDAO;

    private Customer customer;
    private List<Customer> list;

    @PostConstruct
    public void init() {
        customer = new Customer();
        list = customerDAO.findAll();
    }

    public void saveCustomer(ActionEvent event) {

        customer = customerDAO.persist(this.customer);
        list = customerDAO.findAll();
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public List<Customer> getList() {
        return list;
    }

    public void setList(List<Customer> list) {
        this.list = list;
    }

}

当我使用非泛型DAO时,一切似乎都可以完美工作,但是当我尝试使用泛型DAO时,我会得到以下异常:

SEVERE: EJB5070: Exception creating stateless session bean : [CustomerDAO]
WARNING: EJB5184:A system exception occurred during an invocation on EJB CustomerDAO, method: public java.util.List example.BaseDAO.findAll()
WARNING: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:454)
    at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2547)
    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1899)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    at $Proxy216.findAll(Unknown Source)
    at example.__EJB31_Generated__CustomerDAO__Intf____Bean__.findAll(Unknown Source)
    at example.CustomerController.init(CustomerController.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.glassfish.faces.integration.GlassFishInjectionProvider$2.run(GlassFishInjectionProvider.java:382)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.glassfish.faces.integration.GlassFishInjectionProvider.invokeLifecycleMethod(GlassFishInjectionProvider.java:376)
    at org.glassfish.faces.integration.GlassFishInjectionProvider.invokePostConstruct(GlassFishInjectionProvider.java:306)
    at org.glassfish.faces.integration.GlassFishInjectionProvider.invokePostConstruct(GlassFishInjectionProvider.java:229)
    at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
    at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
    at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
    at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
    at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
    at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UISelectItems.getValue(UISelectItems.java:129)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.faces.facelets.util.DevTools.writeAttributes(DevTools.java:375)
    at com.sun.faces.facelets.util.DevTools.writeStart(DevTools.java:424)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:245)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:264)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:264)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:264)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:264)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:264)
    at com.sun.faces.facelets.util.DevTools.debugHtml(DevTools.java:128)
    at com.sun.faces.renderkit.RenderKitUtils.renderHtmlErrorPage(RenderKitUtils.java:1162)
    at com.sun.faces.context.ExceptionHandlerImpl.throwIt(ExceptionHandlerImpl.java:276)
    at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:142)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:726)
    at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:247)
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:449)
    ... 74 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:534)
    at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:95)
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:724)
    ... 76 more
Caused by: java.lang.InstantiationException: example.CustomerDAO
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:325)
    at com.sun.ejb.containers.BaseContainer._constructEJBInstance(BaseContainer.java:1663)
    at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1646)
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:475)
    ... 78 more

是的,请添加嵌套异常。 - perissf
基本上问题现在似乎是这样的:异常描述:解析查询时出现语法错误[SELECT e FROM example.Customer e],因为如果我尝试使用Criteria Query而不是JPQL,则一切正常。 - ChrisGeo
由于这个问题与之前的完全不同,您应该回滚编辑,并在阅读有关JPQL的教程后开启一个新问题。 - perissf
@ChrisGeo,嗨Chris。我有同样的问题,但perissf的答案没有帮助。你能给予任何建议吗? - Mikael S.
2个回答

5
当使用无参构造函数创建子类时(在注入过程中背后自动调用),您需要提供超类的适当构造函数:
public CustomerDAO() {
    super(Customer.class);
}

@ChrisGeo:没错。这就是为什么我问你第一次在哪里实例化你的bean。然而,如果你让JSF来实例化它,你需要一个无参构造函数。祝好。 - Rodmar Conde
我已经进行了更改,但是仍然出现错误,尽管“严重错误”已经消失。我将相应地更新堆栈跟踪和代码,以便您可以查看。 - ChrisGeo

2

根据您的异常信息,您的EJB无法被注入:

@EJB
private CustomerDAO customerDAO;

这意味着您的CustomerDAO对象尚未被创建。您第一次尝试在哪里创建它?
粘贴完整的堆栈跟踪源代码可以提供更多线索。
问候,

我刚刚发布了来自服务器日志(Glassfish)的完整堆栈跟踪。控制器类是我正在尝试创建 EJB 的唯一类。因此,那行代码是我执行的唯一 EJB 注入。 - ChrisGeo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接