无法创建Bean Managed Persistence的实例

时间:2014-11-23 09:59:18

标签: ejb openejb tomee

比赛是: TomEE 7.0 openEjb 4.7.1 。我正在尝试创建实体Bean的实例, EJB实体2.1 BMP (Bean管理持久性)。

bean的部署工作正常,也是在客户端示例应用程序上创建远程home接口,但是当我尝试创建实体bean的istance时,会发生错误。

实体的代码是:

主页界面 BmpEntityHome.java

package it.enzo.ejb.entity.bmp;

import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.ejb.FinderException;

public interface BmpEntityHome extends EJBHome {

    //Metodo Creazione
    public BmpEntityBean createObject(String id) throws RemoteException, CreateException;

    //Metodo finder
    public BmpEntityBean findByPrimaryKey(String key) throws RemoteException, FinderException;

    //Metodo di logica personalizzato
    //public int getMetodoPersonalizzato() throws RemoteException;

}

远程接口 BmpEntityObject.java

package it.enzo.ejb.entity.bmp;

import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface BmpEntityObject extends EJBObject{

    public String getId() throws RemoteException;
    public void setId(String id) throws RemoteException;
    public String getValore1() throws RemoteException;
    public void setValore1(String x) throws RemoteException;
    public String getValore2() throws RemoteException;
    public void setValore2(String x) throws RemoteException;

    public int getAddizzione() throws RemoteException;

    //Metodo di logica
    //public void addizziona(int a, int b) throws RemoteException;
}

Bean接口 BmpEntityBean.java

package it.enzo.ejb.entity.bmp;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;

public class BmpEntityBean implements EntityBean{

    private static final long serialVersionUID = 1L;

    private EntityContext ectx;

    private String iD;
    private String valore1;
    private String valore2;
    private int addizzione;

    //Costruttore
    public BmpEntityBean(){
        System.out.println("BmbRntityBean chiamato il costruttore");
    }


    //Metodo di business
    public void addizziona(int a, int b){
        this.addizzione = a + b;
    }

    //Metodi getter e setter
    public String getId() {
        return iD;
    }


    public void setId(String iD) {
        this.iD = iD;
    }
    public String getValore1() {
        return valore1;
    }


    public void setValore1(String valore1) {
        this.valore1 = valore1;
    }


    public String getValore2() {
        return valore2;
    }


    public void setValore2(String valore2) {
        this.valore2 = valore2;
    }


    public int getAddizzione() {
        return addizzione;
    }

    //Metodo privato per creare la connessione al DB
    private Connection getConnection(){
        Connection cnn = null;
        try {
            Class.forName("org.sqlite.JDBC");
            cnn = DriverManager.getConnection("jdbc:sqlite:EJBdatabase.db");
            this.CreaTabelle(cnn);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return cnn;
    }
    private void CreaTabelle(Connection cnn){
        Statement stat = null;
        try {
            stat = cnn.createStatement();
            stat.executeUpdate("CREATE TABLE if not exists BmpEntityBeanTable (id string primary key, valore1 string, valore2 string, addizzione integer)");
            stat.close();

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                stat.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    //Metodo finder
    public String ejbFindByPrimaryKey(String key) throws FinderException{

        PreparedStatement pstm = null;
        Connection cnn = null;

            try{
                cnn = this.getConnection();
                pstm = cnn.prepareStatement("SELECT id FROM BmpEntityBeanTable WHERE id = ?");
                pstm.setString(1, key);

                ResultSet rs = pstm.executeQuery();
                if(rs.next())return key;

            }catch(Exception e){e.printStackTrace();}
            finally{
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    cnn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            throw new FinderException("Entity con id "+key+" non Trovato");

    }

    //Metodo personalizzato sull'oggetto Home
    //public int ejbHomeGetMetodoPersonalizzato(){
        //return 2976;
    //}


    //Metodi di callback richiamati dal container

    //Metodo di creazione

    public BmpEntityBean ejbCreateObject(String id) throws CreateException{

        Connection cnn = null;
        PreparedStatement pstm = null;

        this.iD = id;

        try{
            cnn = this.getConnection();
            pstm = cnn.prepareStatement("INSERT INTO BmpEntityBeanTable (id) values ('"+id+"')");
            pstm.execute();

            return this;

        }catch(Exception e){e.printStackTrace();}
        finally{
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                cnn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


        throw new CreateException();

    }
    @Override
    public void setEntityContext(EntityContext ctx) throws EJBException,
            RemoteException {
        // TODO Auto-generated method stub
        this.ectx = ctx;
    }


    @Override
    public void unsetEntityContext() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
        this.ectx = null;
    }


    @Override
    public void ejbRemove() throws RemoveException, EJBException,
            RemoteException {
        // TODO Auto-generated method stub

        String key = (String) this.ectx.getPrimaryKey();
        String id = key;

        Connection cnn = null;
        PreparedStatement pstm = null;

        try{
            cnn = this.getConnection();
            pstm = cnn.prepareStatement("DELETE FROM BmpEntityBeanTable WHERE id = ?");
            pstm.setString(1, id);
            pstm.execute();


        }catch(Exception e){e.printStackTrace();}
        finally{
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                cnn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    @Override
    public void ejbActivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub

    }


    @Override
    public void ejbPassivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub

    }


    @Override
    public void ejbLoad() throws EJBException, RemoteException {
        // TODO Auto-generated method stub

        String key = (String) this.ectx.getPrimaryKey();
        String id = key;

        Connection cnn = null;
        PreparedStatement pstm = null;

        try{
            cnn = this.getConnection();
            pstm = cnn.prepareStatement("SELECT * FROM BmpEntityBeanTable WHERE id = ?");
            pstm.setString(1, id);
            ResultSet rs = pstm.executeQuery();
            if(rs.next()){
                this.iD = id;
                this.valore1 = rs.getString("valore1");
                this.valore2 = rs.getString("valore2");
                this.addizzione = rs.getInt("addizzione");
            }
            rs.close();


        }catch(Exception e){e.printStackTrace();}
        finally{
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                cnn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }


    @Override
    public void ejbStore() throws EJBException, RemoteException {
        // TODO Auto-generated method stub

        String key = (String) this.ectx.getPrimaryKey();
        String id = key;

        Connection cnn = null;
        PreparedStatement pstm = null;

        try{
            cnn = this.getConnection();
            pstm = cnn.prepareStatement("UPDATE BmpEntityBeanTable set valore1 = ?, valore2 = ?, addizione = ? WHERE id = ?");
            pstm.setString(1, this.valore1);
            pstm.setString(2, this.valore2);
            pstm.setInt(3, this.addizzione);
            pstm.setString(4, id);
            pstm.execute();


        }catch(Exception e){e.printStackTrace();}
        finally{
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                cnn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }



}

部署desciptor ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" 
    version="2.1">

  <enterprise-beans>

    <entity>
        <ejb-name>BmpEntity</ejb-name>
        <home>it.enzo.ejb.entity.bmp.BmpEntityHome</home>
        <remote>it.enzo.ejb.entity.bmp.BmpEntityObject</remote>
        <ejb-class>it.enzo.ejb.entity.bmp.BmpEntityBean</ejb-class>
        <persistence-type>Bean</persistence-type>
        <prim-key-class>java.lang.String</prim-key-class>
        <reentrant>false</reentrant>
        <primkey-field>iD</primkey-field>
    </entity>


  </enterprise-beans>

 <assembly-descriptor>
    <container-transaction>
      <method>
        <ejb-name>BmpEntity</ejb-name>
        <method-name>*</method-name>
      </method>
      <trans-attribute>Required</trans-attribute>
    </container-transaction>
  </assembly-descriptor>
</ejb-jar>

客户端示例应用

package it.enzo;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;

import javax.ejb.CreateException;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ProvaServ
 */
@WebServlet("/ProvaServ")
public class ProvaServ extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private it.enzo.ejb.entity.bmp.BmpEntityHome bmpEntityHome = null;

    public ProvaServ() {
        super();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");

        PrintWriter out = response.getWriter();

        String comm = request.getParameter("comm");
        if(comm!=null){
            switch(comm.toString()){

            case "bmpEntity_Start":
                this.bmpEntityHome = null;
                this.callBmpEntity();

            break;

            case "bmpEntity_Create":
                if(this.bmpEntityHome!=null){
                    try {
                        String id = request.getParameter("id");
                        //it.enzo.ejb.entity.bmp.BmpEntityBean bmpEntityBean_TMP = 
                        this.bmpEntityHome.createObject(id);
                        out.print("BmpEntity aggiunto: ");//+bmpEntityBean_TMP.getId());
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } 
            break;

            }

        }

        out.print("<div><form action=''>"
                +"<input type='hidden' name='comm' value='bmpEntity_Create'>"
                +"Aggiungi un BmpEntity <input type='text' name='id' value='ID-DELL-ENTITY-1'>"
                +"<input type='submit' value='Aggiungi'>"
                +"</form></div>");

        out.print("<br><br><a href='?comm=bmpEntity_Start'>Start BMPEntity</a><br>");
    }


private void callBmpEntity(){

    if(this.bmpEntityHome==null){
    Properties p = new Properties();
    p.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
    p.put("java.naming.provider.url", "http://localhost:8080/tomee/ejb");

    InitialContext initialContext;
    Object object = null;
    try { 
        initialContext = new InitialContext(p);

        object = initialContext.lookup("BmpEntityRemoteHome");

        this.bmpEntityHome = (it.enzo.ejb.entity.bmp.BmpEntityHome)
                PortableRemoteObject.narrow(object, it.enzo.ejb.entity.bmp.BmpEntityHome.class);

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }
    }
} 
}

堆栈错误

nov 23, 2014 9:36:48 AM org.apache.openejb.core.transaction.EjbTransactionUtil handleSystemException
GRAVE: EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
    at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
    at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
    at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
    at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
    at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

java.rmi.RemoteException: The bean encountered a non-application exception; nested exception is: 
    java.lang.IllegalArgumentException: object is not an instance of declaring class
    at org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException(EjbTransactionUtil.java:155)
    at org.apache.openejb.core.entity.EntityContainer.handleException(EntityContainer.java:484)
    at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:369)
    at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
    at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
    at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
    at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
    at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
    ... 25 more

openejb-core-4.7.1.jar

的类 EntityContainer.class 中的错误来源
....
protected ProxyInfo createEJBObject(final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType type) throws OpenEJBException {
        final BeanContext beanContext = callContext.getBeanContext();

        callContext.setCurrentOperation(Operation.CREATE);

        /*
        * According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
        * method executes in the same transaction context as the previous ejbCreate(...) method."
        *
        * For this reason the TransactionScopeHandler methods usally preformed by the invoke( )
        * operation must be handled here along with the call explicitly.
        * This ensures that the afterInvoke() is not processed between the ejbCreate and ejbPostCreate methods to
        * ensure that the ejbPostCreate executes in the same transaction context of the ejbCreate.
        * This would otherwise not be possible if container-managed transactions were used because
        * the TransactionScopeManager would attempt to commit the transaction immediately after the ejbCreate
        * and before the ejbPostCreate had a chance to execute.  Once the ejbPostCreate method execute the
        * super classes afterInvoke( ) method will be executed committing the transaction if its a CMT.
        */

        final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);

        EntityBean bean = null;
        Object primaryKey = null;
        try {
            // Get new ready instance
            bean = instanceManager.obtainInstance(callContext);

            // Obtain the proper ejbCreate() method
            final Method ejbCreateMethod = beanContext.getMatchingBeanMethod(callMethod);


            //HERE THE ERROR
            // invoke the ejbCreate which returns the primary key
            primaryKey = ejbCreateMethod.invoke(bean, args);//HERE THE ERROR

            didCreateBean(callContext, bean);

            // determine post create callback method
            final Method ejbPostCreateMethod = beanContext.getMatchingPostCreateMethod(ejbCreateMethod);

            // create a new context containing the pk for the post create call
            final ThreadContext postCreateContext = new ThreadContext(beanContext, primaryKey);
            postCreateContext.setCurrentOperation(Operation.POST_CREATE);

            final ThreadContext oldContext = ThreadContext.enter(postCreateContext);
            try {
                // Invoke the ejbPostCreate method on the bean instance
                ejbPostCreateMethod.invoke(bean, args);

                // According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
                // method executes in the same transaction context as the previous ejbCreate(...) method."
                //
                // The bean is first insterted using db.create( ) and then after ejbPostCreate( ) its
                // updated using db.update(). This protocol allows for visablity of the bean after ejbCreate
                // within the current trasnaction.
            } finally {
                ThreadContext.exit(oldContext);
            }

            // update pool
            instanceManager.poolInstance(callContext, bean, primaryKey);
        } catch (final Throwable e) {
            handleException(txPolicy, e, callContext, bean);
        } finally {
            afterInvoke(txPolicy, callContext);
        }

        return new ProxyInfo(beanContext, primaryKey);

    }
....

当我在客户端示例中尝试此操作时:

....
this.bmpEntityHome.createObject(id);
....
openejb-core-4.7.1.jar 类EntityContainer.class 中的

称为此方法:

...
protected ProxyInfo createEJBObject(final Method callMethod, final Object[]...
...

并在第340行指示:

...
// invoke the ejbCreate which returns the primary key
primaryKey = ejbCreateMethod.invoke(bean, args);
...

生成异常:

...
EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
...

感谢!

1 个答案:

答案 0 :(得分:1)

已解决...我错过了BmpEntityBean.class类(Business class)中的'ejbPostCreate'方法....