Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Entity Beans, Oracle and RI - please help

0 views
Skip to first unread message

Jason Mowat

unread,
Oct 30, 2002, 1:48:33 PM10/30/02
to
Greets,

I've been trying to create a "SIMPLE" entity bean sample hooked into my
Oracle database, but I seem to be thwarted at every turn. Essentially, I
have created a BMP entity bean to a table called TBL_RPT_TYPE (a lookup
table of report types). I made the bean remote through the implementation
of the remote interfaces. I also created a simple client to add a new "row"
and query an existing "row". All I get is loads of weird errors.

I'm pretty sure my Oracle connection is set up properly, and my bean "looks"
OK. And my client is SUPER-SIMPLE. Perhaps someone else with a bit more
experience can see what I can't.

I'll provide as much code as possible. It could be a little lengthy...

/**
* The main entity bean
*/
package data;

import java.sql.*;
import javax.sql.*;
import java.util.*;
import java.math.*;
import javax.ejb.*;
import javax.naming.*;

public class ReportTypeBean implements EntityBean {

private String id;
private String name;
private EntityContext context;
private Connection con;
private String dbName = "java:comp/env/jdbc/Oracle";


public String getName() {

return name;
}

public String ejbCreate(String id, String name)
throws CreateException {


try {
insertRow(id, name);
} catch (Exception ex) {
throw new EJBException("ejbCreate: " +
ex.getMessage());
}

this.id = id;
this.name = name;
return id;
}

public String ejbFindByPrimaryKey(String primaryKey)
throws FinderException {

boolean result;

try {
result = selectByPrimaryKey(primaryKey);
} catch (Exception ex) {
throw new EJBException("ejbFindByPrimaryKey: " +
ex.getMessage());
}
if (result) {
return primaryKey;
}
else {
throw new ObjectNotFoundException
("Row for id " + primaryKey + " not found.");
}
}

public Collection ejbFindByName(String name)
throws FinderException {

Collection result;

try {
result = selectByName(name);
} catch (Exception ex) {
throw new EJBException("ejbFindByName " +
ex.getMessage());
}
return result;
}

public void ejbRemove() {

try {
deleteRow(id);
} catch (Exception ex) {
throw new EJBException("ejbRemove: " +
ex.getMessage());
}
}

public void setEntityContext(EntityContext context) {

this.context = context;
try {
makeConnection();
} catch (Exception ex) {
throw new EJBException("Unable to connect to database. " +
ex.getMessage());
}
}

public void unsetEntityContext() {

try {
con.close();
} catch (SQLException ex) {
throw new EJBException("unsetEntityContext: " + ex.getMessage());
}
}

public void ejbActivate() {
id = (String)context.getPrimaryKey();
}

public void ejbPassivate() {
id = null;
}

public void ejbLoad() {

try {
loadRow();
} catch (Exception ex) {
throw new EJBException("ejbLoad: " +
ex.getMessage());
}
}

public void ejbStore() {

try {
storeRow();
} catch (Exception ex) {
throw new EJBException("ejbStore: " +
ex.getMessage());
}
}


public void ejbPostCreate(String id, String name) { }


/*********************** Database Routines *************************/

private void makeConnection() throws NamingException, SQLException {

InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
}

private void insertRow (String id, String name) throws SQLException {

String insertStatement =
"insert into tbl_rpt_type values ( ? , ? , ? , ? )";
PreparedStatement prepStmt =
con.prepareStatement(insertStatement);

prepStmt.setString(1, id);
prepStmt.setString(2, name);
prepStmt.setString(3, null);
prepStmt.setString(4, null);

prepStmt.executeUpdate();
prepStmt.close();
}

private void deleteRow(String id) throws SQLException {

String deleteStatement =
"delete from tbl_rpt_type where report_type_id = ? ";
PreparedStatement prepStmt =
con.prepareStatement(deleteStatement);

prepStmt.setString(1, id);
prepStmt.executeUpdate();
prepStmt.close();
}

private boolean selectByPrimaryKey(String primaryKey)
throws SQLException {

String selectStatement =
"select report_type_id " +
"from tbl_rpt_type where report_type_id = '?' ";
PreparedStatement prepStmt =
con.prepareStatement(selectStatement);
prepStmt.setString(1, primaryKey);

ResultSet rs = prepStmt.executeQuery();
boolean result = rs.next();
prepStmt.close();
return result;
}

private Collection selectByName(String name)
throws SQLException {

String selectStatement =
"select report_type_id " +
"from tbl_rpt_type where report_name = ? ";
PreparedStatement prepStmt =
con.prepareStatement(selectStatement);

prepStmt.setString(1, name);
ResultSet rs = prepStmt.executeQuery();
ArrayList a = new ArrayList();

while (rs.next()) {
String id = rs.getString(1);
a.add(id);
}

prepStmt.close();
return a;
}

private void loadRow() throws SQLException {

String selectStatement =
"select name " +
"from tbl_rpt_type where report_type_id = ? ";
PreparedStatement prepStmt =
con.prepareStatement(selectStatement);

prepStmt.setString(1, this.id);

ResultSet rs = prepStmt.executeQuery();

if (rs.next()) {
this.name = rs.getString(1);
prepStmt.close();
}
else {
prepStmt.close();
throw new NoSuchEntityException("Row for id " + id +
" not found in database.");
}
}


private void storeRow() throws SQLException {

String updateStatement =
"update tbl_rpt_type set report_name = ? " +
"where report_type_id = ?";
PreparedStatement prepStmt =
con.prepareStatement(updateStatement);

prepStmt.setString(1, name);
prepStmt.setString(2, id);
int rowCount = prepStmt.executeUpdate();
prepStmt.close();

if (rowCount == 0) {
throw new EJBException("Storing row for id " + id + " failed.");
}
}
}

/**
* The bean's remote interface
*/
package data;

import java.rmi.*;
import javax.ejb.*;

public interface ReportType extends EJBObject {
public String getName() throws RemoteException;
}

/**
* The bean's home interface
*/
package data;

import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;

public interface ReportTypeHome extends EJBHome {

public ReportType create(String id, String name)
throws RemoteException, CreateException;

public ReportType findByPrimaryKey(String id)
throws FinderException, RemoteException;

public Collection findByName(String name)
throws FinderException, RemoteException;
}

/**
* The simple client
*/
package client;

import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import data.*;

import java.util.*;

public class SimpleClient {

public static void main(String[] args) {
try {
Context initial = new InitialContext();
Object objref = initial.lookup("java:comp/env/ejb/ReportType");

ReportTypeHome home =
(ReportTypeHome)PortableRemoteObject.narrow(objref,
ReportTypeHome.class);

// Add a new row
ReportType newReportType = home.create("TEST001","Test 1");
System.out.println("Name of new report type = " +
newReportType.getName());
newReportType.remove();

// Find an existing row
Collection c = home.findByName("Purchases");
Iterator i=c.iterator();
while (i.hasNext()) {
ReportType reportTypeByName = (ReportType)i.next();
String id = (String)reportTypeByName.getPrimaryKey();
System.out.println(id + ": " + reportTypeByName);
}

// Find an existing row by it's PK
ReportType existingReportType = home.findByPrimaryKey("RCSR");
System.out.println("Name of existing report type = " +
existingReportType.getName());

System.exit(0);
} catch (Exception ex) {
System.err.println("Caught an exception." );
ex.printStackTrace();
}
}
}

That's the code in a nutshell. Now, the deployment descriptors look as
follows:
/**
* Application DD, which I called "Test"
*/
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE
Application 1.3//EN' 'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<display-name>Test</display-name>
<description>Application description</description>
<module>
<ejb>ejb-jar-ic.jar</ejb>
</module>
<module>
<java>app-client-ic.jar</java>
</module>
<module>
<java>app-client-ic6.jar</java>
</module>
</application>

/**
* Entity bean container and bean DD. I couldn't seem to find my userID or
password for my Oracle connection in here,
* even though I specified it in the RI...
*/
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>

<ejb-jar>
<display-name>data</display-name>
<enterprise-beans>
<entity>
<display-name>ReportTypeBean</display-name>
<ejb-name>ReportTypeBean</ejb-name>
<home>data.ReportTypeHome</home>
<remote>data.ReportType</remote>
<ejb-class>data.ReportTypeBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
<resource-ref>
<res-ref-name>jdbc/Oracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</entity>
</enterprise-beans>
<assembly-descriptor>
<method-permission>
<unchecked />
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getHandle</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>getHomeHandle</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>javax.ejb.Handle</method-param>
</method-params>
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>findByPrimaryKey</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>findByName</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getEJBHome</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>isIdentical</method-name>
<method-params>
<method-param>javax.ejb.EJBObject</method-param>
</method-params>
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>getEJBMetaData</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>remove</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getPrimaryKey</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getName</method-name>
<method-params />
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>java.lang.Object</method-param>
</method-params>
</method>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>create</method-name>
<method-params>
<method-param>java.lang.String</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</method>
</method-permission>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>create</method-name>
<method-params>
<method-param>java.lang.String</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getName</method-name>
<method-params />
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>findByName</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>javax.ejb.Handle</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>java.lang.Object</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>remove</method-name>
<method-params />
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>ReportTypeBean</ejb-name>
<method-intf>Home</method-intf>
<method-name>findByPrimaryKey</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

My server configuration is as follows:

JDBC Drivers: oracle.jdbc.driver.OracleDriver
Datasources:
JNDI: jdbc/Oracle
JDBC URL: jdbc:oracle:thin:@142.200.49.221:1521:erep

My bean Resource factory is configured to jdbc/Oracle, and I specify my user
name and password.

My environment file: C:\j2sdkee1.3.1\bin\userconfig.bat, which links to the
Oracle JDBC drivers from my 8.1 client, is as follows:

REM
REM Copyright 2002 Sun Microsystems, Inc. All rights reserved.
REM SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
REM

rem J2EE_CLASSPATH is appended to the classpath referenced by the EJB
server.
rem J2EE_CLASSPATH must include the location of the JDBC driver classes
rem (except for the Cloudscape driver shipped with this release).
rem Each directory is delimited by a semicolon.
rem
set J2EE_CLASSPATH=C:\j2sdkee1.3.1\lib\system\classes12.zip
rem
rem JAVA_HOME refers to the directory where the Java(tm) 2 SDK
rem Standard Edition software is installed.
rem
rem set JAVA_HOME=
rem

I run my simple client by doing the following:

D:\Projects\java\Entity Java Beans\set APPCPATH=testClient.jar
D:\Projects\java\Entity Java Beans\jar>runclient -client test.ear -name
SimpleClient -textauth

This returns the following:

Initiating login ...
Enter Username:guest
Enter Password:guest123
Binding name:`java:comp/env/ejb/ReportType`
Caught an exception.
java.rmi.ServerException: RemoteException occurred in server thread; nested
exce
ption is:
java.rmi.RemoteException: Transaction aborted (possibly due to
transacti
on time out).; nested exception is: javax.transaction.RollbackException:
Transac
tion marked for rollback; nested exception is:
javax.transaction.RollbackException: Transaction marked for rollback
at
com.sun.corba.ee.internal.iiop.ShutdownUtilDelegate.mapSystemExceptio
n(ShutdownUtilDelegate.java:64)
at javax.rmi.CORBA.Util.mapSystemException(Util.java:65)
at data._ReportTypeHome_Stub.create(Unknown Source)
at client.SimpleClient.main(SimpleClient.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:22
9)
at com.sun.enterprise.appclient.Main.main(Main.java:155)
Caused by: java.rmi.RemoteException: Transaction aborted (possibly due to
transa
ction time out).; nested exception is: javax.transaction.RollbackException:
Tran
saction marked for rollback; nested exception is:
javax.transaction.RollbackException: Transaction marked for rollback
at
com.sun.enterprise.iiop.POAProtocolMgr.mapException(POAProtocolMgr.ja
va:389)
at
com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:43
1)
at
data.ReportTypeBean_RemoteHomeImpl.create(ReportTypeBean_RemoteHomeIm
pl.java:37)
at data._ReportTypeBean_RemoteHomeImpl_Tie._invoke(Unknown Source)
at
com.sun.corba.ee.internal.POA.GenericPOAServerSC.dispatchToServant(Ge
nericPOAServerSC.java:520)
at
com.sun.corba.ee.internal.POA.GenericPOAServerSC.internalDispatch(Gen
ericPOAServerSC.java:210)
at
com.sun.corba.ee.internal.POA.GenericPOAServerSC.dispatch(GenericPOAS
erverSC.java:112)
at com.sun.corba.ee.internal.iiop.ORB.process(ORB.java:255)
at
com.sun.corba.ee.internal.iiop.RequestProcessor.process(RequestProces
sor.java:84)
at
com.sun.corba.ee.internal.orbutil.ThreadPool$PooledThread.run(ThreadP
ool.java:99)
Caused by: javax.transaction.RollbackException: Transaction marked for
rollback
at
com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransacti
on.java:161)
at
com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2E
ETransactionManagerOpt.java:243)
at
com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java
:1485)
at
com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:
1289)
at
com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:40
3)
... 8 more

Now, at this point, I'm thinking there is something wrong with the thin
driver and J2EE RI. Or perhaps there is some sort of configuration issue
with Oracle that needs to be addressed before entity bean solutions will
work on it. Does anyone have any ideas? I've been trying quite hard to
solve this issue.

Cheers,
Jason


0 new messages