Unable to create an instance of Bean Managed Persistence

1.6k views Asked by At

the contest is: TomEE 7.0 with openEjb 4.7.1. I'm try to create an instance of an Entity Bean, EJB Entity 2.1 BMP (Bean Managed Persistence).

The Deploy of the bean work fine, also the creating of the remote home interface on a client example application, but when i try to create an istance of the entity bean, an error occur.

The code of the Entity is:

Home interface 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;

}

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

    }



}

Deploy 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>

Client Example application

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

    }
    }
} 
}

the stack error

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

The error origin in the class EntityContainer.class of the package openejb-core-4.7.1.jar

....
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);

    }
....

When i try this in the client example:

....
this.bmpEntityHome.createObject(id);
....

in the class EntityContainer.class of the package openejb-core-4.7.1.jar is called this method:

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

and at the line 340 the instruction:

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

generate the exception:

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

Thank!

1

There are 1 answers

0
Vincenzo D'Aniello On BEST ANSWER

Resolved... i have missed the 'ejbPostCreate' method in BmpEntityBean.class class (Business class)....