User: mulder
Date: 00/09/04 09:17:55
Modified: src/main/org/jboss/ejb/plugins/jaws/jdbc JDBCCommand.java
JDBCFinderCommand.java JDBCLoadEntityCommand.java
Log:
Implement changes suggested by myself and Jay Walters: When fetching data
into a field, use the field's class to determine how to get the data from
the ResultSet. Avoids problems with "getObject" and DB-specific types.
With the class of the field, we know better than the DB drivers what JDBC
type we want.
If we can implement this for writing to PreparedStatements as well, then
we can trim a lot of fat out of the XML configuration files (we will only
need to know SQL types for creating DB tables).
Also, convert java.util.Date object to java.sql.Date, Time, or Timestamp
as appropriate before setting.
Revision Changes Path
1.8 +150 -126 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommand.java
Index: JDBCCommand.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommand.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- JDBCCommand.java 2000/08/29 02:15:24 1.7
+++ JDBCCommand.java 2000/09/04 16:17:54 1.8
@@ -10,6 +10,8 @@
import java.math.BigDecimal;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
@@ -50,33 +52,62 @@
* utility methods that database commands may need to call.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
*/
public abstract class JDBCCommand
{
+ private final static HashMap rsTypes = new HashMap();
+ static {
+ Class[] arg = new Class[]{Integer.TYPE};
+ try {
+ rsTypes.put(java.util.Date.class.getName(),
ResultSet.class.getMethod("getTimestamp", arg));
+ rsTypes.put(java.sql.Date.class.getName(),
ResultSet.class.getMethod("getDate", arg));
+ rsTypes.put(java.sql.Time.class.getName(),
ResultSet.class.getMethod("getTime", arg));
+ rsTypes.put(java.sql.Timestamp.class.getName(),
ResultSet.class.getMethod("getTimestamp", arg));
+ rsTypes.put(java.math.BigDecimal.class.getName(),
ResultSet.class.getMethod("getBigDecimal", arg));
+ rsTypes.put(java.sql.Ref.class.getName(),
ResultSet.class.getMethod("getRef", arg));
+ rsTypes.put(java.lang.String.class.getName(),
ResultSet.class.getMethod("getString", arg));
+ rsTypes.put(java.lang.Boolean.class.getName(),
ResultSet.class.getMethod("getBoolean", arg));
+ rsTypes.put(Boolean.TYPE.getName(),
ResultSet.class.getMethod("getBoolean", arg));
+ rsTypes.put(java.lang.Byte.class.getName(),
ResultSet.class.getMethod("getByte", arg));
+ rsTypes.put(Byte.TYPE.getName(),
ResultSet.class.getMethod("getByte", arg));
+ rsTypes.put(java.lang.Double.class.getName(),
ResultSet.class.getMethod("getDouble", arg));
+ rsTypes.put(Double.TYPE.getName(),
ResultSet.class.getMethod("getDouble", arg));
+ rsTypes.put(java.lang.Float.class.getName(),
ResultSet.class.getMethod("getFloat", arg));
+ rsTypes.put(Float.TYPE.getName(),
ResultSet.class.getMethod("getFloat", arg));
+ rsTypes.put(java.lang.Integer.class.getName(),
ResultSet.class.getMethod("getInt", arg));
+ rsTypes.put(Integer.TYPE.getName(),
ResultSet.class.getMethod("getInt", arg));
+ rsTypes.put(java.lang.Long.class.getName(),
ResultSet.class.getMethod("getLong", arg));
+ rsTypes.put(Long.TYPE.getName(),
ResultSet.class.getMethod("getLong", arg));
+ rsTypes.put(java.lang.Short.class.getName(),
ResultSet.class.getMethod("getShort", arg));
+ rsTypes.put(Short.TYPE.getName(),
ResultSet.class.getMethod("getShort", arg));
+ } catch(NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
// Attributes ----------------------------------------------------
-
+
protected JDBCCommandFactory factory;
protected MetaInfo metaInfo;
protected Log log;
protected String name; // Command name, used for debug trace
-
+
private String sql;
private static Map jdbcTypeNames;
-
+
/**
* Gives compile-time control of tracing.
*/
public static boolean debug = true;
-
+
// Constructors --------------------------------------------------
-
+
/**
* Construct a JDBCCommand with given factory and name.
*
- * @param factory the factory which was used to create this JDBCCommand,
+ * @param factory the factory which was used to create this JDBCCommand,
* which is also used as a common repository, shared by all an
- * entity's Commands.
+ * entity's Commands.
* @param name the name to be used when tracing execution.
*/
protected JDBCCommand(JDBCCommandFactory factory, String name)
@@ -86,9 +117,9 @@
this.log = factory.getLog();
this.name = name;
}
-
+
// Protected -----------------------------------------------------
-
+
/**
* Template method handling the mundane business of opening
* a database connection, preparing a statement, setting its parameters,
@@ -108,7 +139,7 @@
Connection con = null;
PreparedStatement stmt = null;
Object result = null;
-
+
try
{
con = getConnection();
@@ -120,6 +151,9 @@
stmt = con.prepareStatement(theSQL);
setParameters(stmt, argOrArgs);
result = executeStatementAndHandleResult(stmt, argOrArgs);
+ } catch(SQLException e) {
+ log.exception(e);
+ throw e;
} finally
{
if (stmt != null)
@@ -143,10 +177,10 @@
}
}
}
-
+
return result;
}
-
+
/**
* Used to set static SQL in subclass constructors.
*
@@ -160,7 +194,7 @@
}
this.sql = sql;
}
-
+
/**
* Gets the SQL to be used in the PreparedStatement.
* The default implementation returns the <code>sql</code> field value.
@@ -172,14 +206,14 @@
* @param argOrArgs argument or array of arguments passed in from
* subclass execute method.
* @return the SQL to use in the PreparedStatement.
- * @throws Exception if an attempt to generate dynamic SQL results in
+ * @throws Exception if an attempt to generate dynamic SQL results in
* an Exception.
*/
protected String getSQL(Object argOrArgs) throws Exception
{
return sql;
}
-
+
/**
* Default implementation does nothing.
* Override if parameters need to be set.
@@ -193,7 +227,7 @@
throws Exception
{
}
-
+
/**
* Executes the PreparedStatement and handles result of successful execution.
* This is implemented in subclasses for queries and updates.
@@ -206,11 +240,11 @@
* @throws Exception if execution or result handling fails.
*/
protected abstract Object executeStatementAndHandleResult(
- PreparedStatement stmt,
+ PreparedStatement stmt,
Object argOrArgs) throws Exception;
-
+
// ---------- Utility methods for use in subclasses ----------
-
+
/**
* Sets a parameter in this Command's PreparedStatement.
* Handles null values, and provides tracing.
@@ -234,20 +268,30 @@
", value=" +
((value == null) ? "NULL" : value));
}
-
+
if (value == null) {
stmt.setNull(idx, jdbcType);
} else {
+ if(jdbcType == Types.DATE) {
+ if(value.getClass().getName().equals("java.util.Date"))
+ value = new java.sql.Date(((java.util.Date)value).getTime());
+ } else if(jdbcType == Types.TIME) {
+ if(value.getClass().getName().equals("java.util.Date"))
+ value = new java.sql.Time(((java.util.Date)value).getTime());
+ } else if(jdbcType == Types.TIMESTAMP) {
+ if(value.getClass().getName().equals("java.util.Date"))
+ value = new java.sql.Timestamp(((java.util.Date)value).getTime());
+ }
if (jdbcType == Types.JAVA_OBJECT) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
+
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
-
+
oos.writeObject(value);
-
+
oos.close();
-
+
} catch (IOException e) {
throw new SQLException("Can't write Java object type to DB: " +
e);
}
@@ -258,7 +302,7 @@
}
}
}
-
+
/**
* Sets the PreparedStatement parameters for a primary key
* in a WHERE clause.
@@ -269,7 +313,7 @@
* @param id the entity's ID
* @return the index of the next unset parameter
* @throws SQLException if parameter setting fails
- * @throws IllegalAccessException if accessing a field in the PK class fails
+ * @throws IllegalAccessException if accessing a field in the PK class fails
*/
protected int setPrimaryKeyParameters(PreparedStatement stmt,
int parameterIndex,
@@ -277,7 +321,7 @@
throws IllegalAccessException, SQLException
{
Iterator it = metaInfo.getPkFieldInfos();
-
+
if (metaInfo.hasCompositeKey())
{
while (it.hasNext())
@@ -293,18 +337,18 @@
int jdbcType = pkFieldInfo.getJDBCType();
setParameter(stmt, parameterIndex++, jdbcType, id);
}
-
+
return parameterIndex;
}
-
+
/**
- * Sets parameter(s) representing a foreign key in this
+ * Sets parameter(s) representing a foreign key in this
* Command's PreparedStatement.
* TODO: (JF) tighten up the typing of the value parameter.
*
* @param stmt the PreparedStatement whose parameters need to be set.
* @param idx the index (1-based) of the first parameter to be set.
- * @param fieldInfo the CMP meta-info for the field containing the
+ * @param fieldInfo the CMP meta-info for the field containing the
* entity reference.
* @param value the entity (EJBObject) referred to by the reference
* (may be null).
@@ -320,7 +364,7 @@
{
JawsCMPField[] pkInfo = fieldInfo.getForeignKeyCMPFields();
Object pk = null;
-
+
if (value != null)
{
try
@@ -331,7 +375,7 @@
throw new SQLException("Could not extract primary key from EJB
reference:"+e);
}
}
-
+
if (!((JawsEntity)pkInfo[0].getBeanContext()).getPrimaryKeyField().equals(""))
{
// Primitive key
@@ -358,93 +402,73 @@
return idx+pkInfo.length;
}
}
-
+
/**
* Used for all retrieval of results from <code>ResultSet</code>s.
* Implements tracing, and allows some tweaking of returned types.
*
* @param rs the <code>ResultSet</code> from which a result is being retrieved.
* @param idx index of the result column.
- * @param jdbcType the JDBC type which this result is expected to be
- * compatible with.
+ * @param destination The class of the variable this is going into
*/
- protected Object getResultObject(ResultSet rs, int idx, int jdbcType)
- throws SQLException{
+ protected Object getResultObject(ResultSet rs, int idx, Class destination)
+ throws SQLException{
- Object result = null;
+ Object result = null;
- if (jdbcType != Types.JAVA_OBJECT) {
- result = rs.getObject(idx);
- } else {
- // Also we should detect the EJB references here
-
- // Get the underlying byte[]
-
- byte[] bytes = rs.getBytes(idx);
-
- if( bytes == null ) {
- result = null;
- } else {
- // We should really reuse these guys
-
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- // Use the class loader to deserialize
-
- try {
- ObjectInputStream ois = new ObjectInputStream(bais);
- result = ois.readObject();
-
- ois.close();
- } catch (IOException e) {
- throw new SQLException("Can't read Java object try from DB: " +
e);
- } catch (ClassNotFoundException e) {
- throw new SQLException("Can't read Java object try from DB: " +
e);
- }
- }
- }
-
- // Result transformation required by Oracle, courtesy of Jay Walters
-
- if (result instanceof BigDecimal)
- {
- BigDecimal bigDecResult = (BigDecimal)result;
-
- switch (jdbcType)
- {
- case Types.INTEGER:
- result = new Integer(bigDecResult.intValue());
- break;
-
- case Types.BIT:
- result = new Boolean(bigDecResult.intValue() > 0);
- break;
-
- case Types.DOUBLE:
- result = new Double(bigDecResult.doubleValue());
- break;
-
- case Types.FLOAT:
- result = new Float(bigDecResult.floatValue());
- break;
-
- case Types.BIGINT:
- result = new Long(bigDecResult.longValue());
- break;
- }
- }
+ Method method = (Method)rsTypes.get(destination.getName());
+ if(method != null) {
+ try {
+ result = method.invoke(rs, new Object[]{new Integer(idx)});
+ if(rs.wasNull()) return null;
+ return result;
+ } catch(IllegalAccessException e) {
+ System.out.println("Unable to read from ResultSet: "+e);
+ } catch(InvocationTargetException e) {
+ System.out.println("Unable to read from ResultSet: "+e);
+ }
+ }
- if (debug) {
- String className = result == null ? "null" : result.getClass().getName();
- log.debug("Got result: idx=" + idx +
- ", value=" + result +
- ", class=" + className +
- ", JDBCtype=" + getJDBCTypeName(jdbcType));
- }
-
- return result;
- }
-
+ result = rs.getObject(idx);
+ if(result == null)
+ return null;
+ if(destination.isAssignableFrom(result.getClass()))
+ return result;
+
+ // Also we should detect the EJB references here
+
+ // Get the underlying byte[]
+
+ byte[] bytes = rs.getBytes(idx);
+
+ if( bytes == null ) {
+ result = null;
+ } else {
+ // We should really reuse these guys
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ // Use the class loader to deserialize
+
+ try {
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ result = ois.readObject();
+ if(!destination.isAssignableFrom(result.getClass())) {
+ result = null;
+ System.out.println("Unable to load a ResultSet column into a
variable of type '"+destination.getName()+"'");
+ }
+
+ ois.close();
+ } catch (IOException e) {
+ throw new SQLException("Unable to load a ResultSet column into a
variable of type '"+destination.getName()+"'");
+ } catch (ClassNotFoundException e) {
+ throw new SQLException("Unable to load a ResultSet column into a
variable of type '"+destination.getName()+"'");
+ }
+ }
+
+ return result;
+ }
+
/**
* Gets the integer JDBC type code corresponding to the given name.
*
@@ -465,7 +489,7 @@
return Types.OTHER;
}
}
-
+
/**
* Gets the JDBC type name corresponding to the given type code.
*
@@ -479,10 +503,10 @@
{
setUpJDBCTypeNames();
}
-
+
return (String)jdbcTypeNames.get(new Integer(jdbcType));
}
-
+
/**
* Returns the comma-delimited list of primary key column names
* for this entity.
@@ -504,7 +528,7 @@
}
return sb.toString();
}
-
+
/**
* Returns the string to go in a WHERE clause based on
* the entity's primary key.
@@ -528,7 +552,7 @@
}
return sb.toString();
}
-
+
// MF: PERF!!!!!!!
protected Object[] getState(EntityEnterpriseContext ctx)
{
@@ -547,17 +571,17 @@
return null;
}
}
-
+
return state;
}
-
+
protected Object getCMPFieldValue(Object instance, CMPFieldInfo fieldInfo)
throws IllegalAccessException
{
Field field = fieldInfo.getField();
return field.get(instance);
}
-
+
protected void setCMPFieldValue(Object instance,
CMPFieldInfo fieldInfo,
Object value)
@@ -566,23 +590,23 @@
Field field = fieldInfo.getField();
field.set(instance, value);
}
-
+
protected Object getPkFieldValue(Object pk, PkFieldInfo pkFieldInfo)
throws IllegalAccessException
{
Field field = pkFieldInfo.getPkField();
return field.get(pk);
}
-
+
// This is now only used in setForeignKey
-
+
protected int getJawsCMPFieldJDBCType(JawsCMPField fieldInfo)
{
return getJDBCType(fieldInfo.getJdbcType());
}
-
+
// Private -------------------------------------------------------
-
+
/** Get a database connection */
private Connection getConnection() throws SQLException
{
@@ -596,11 +620,11 @@
return DriverManager.getConnection(url,"sa","");
}
}
-
+
private final void setUpJDBCTypeNames()
{
jdbcTypeNames = new HashMap();
-
+
Field[] fields = Types.class.getFields();
int length = fields.length;
for (int i = 0; i < length; i++) {
1.5 +18 -19
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFinderCommand.java
Index: JDBCFinderCommand.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFinderCommand.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- JDBCFinderCommand.java 2000/08/24 10:56:36 1.4
+++ JDBCFinderCommand.java 2000/09/04 16:17:54 1.5
@@ -33,28 +33,28 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*/
-public abstract class JDBCFinderCommand
+public abstract class JDBCFinderCommand
extends JDBCQueryCommand
implements JPMFindEntitiesCommand
{
// Constructors --------------------------------------------------
-
+
public JDBCFinderCommand(JDBCCommandFactory factory, String name)
{
super(factory, name);
}
-
+
// JPMFindEntitiesCommand implementation -------------------------
-
+
public Collection execute(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx)
throws RemoteException, FinderException
{
Collection result = null;
-
+
try
{
result = (Collection)jdbcExecute(args);
@@ -63,16 +63,16 @@
log.exception(e);
throw new FinderException("Find failed");
}
-
+
return result;
}
-
+
// JDBCQueryCommand overrides ------------------------------------
-
+
protected Object handleResult(ResultSet rs, Object argOrArgs) throws Exception
{
Collection result = new ArrayList();
-
+
if (metaInfo.hasCompositeKey())
{
// Compound key
@@ -83,14 +83,14 @@
Object pk = metaInfo.getPrimaryKeyClass().newInstance();
int i = 1; // parameter index
Iterator it = metaInfo.getPkFieldInfos();
-
+
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
Field pkField = pkFieldInfo.getPkField();
- pkField.set(pk, getResultObject(rs,
- i++,
- pkFieldInfo.getJDBCType()));
+ pkField.set(pk, getResultObject(rs,
+ i++,
+ pkField.getType()));
}
result.add(pk);
}
@@ -101,17 +101,16 @@
} else
{
// Primitive key
-
+
Iterator it = metaInfo.getPkFieldInfos();
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
- int jdbcType = pkFieldInfo.getJDBCType();
-
+
while (rs.next())
{
- result.add(getResultObject(rs, 1, jdbcType));
+ result.add(getResultObject(rs, 1, pkFieldInfo.getPkField().getType()));
}
}
-
+
return result;
}
}
1.4 +38 -39
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntityCommand.java
Index: JDBCLoadEntityCommand.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntityCommand.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- JDBCLoadEntityCommand.java 2000/08/24 10:56:36 1.3
+++ JDBCLoadEntityCommand.java 2000/09/04 16:17:54 1.4
@@ -34,32 +34,32 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
- * @version $Revision: 1.3 $
+ * @version $Revision: 1.4 $
*/
public class JDBCLoadEntityCommand
extends JDBCQueryCommand
implements JPMLoadEntityCommand
{
// Constructors --------------------------------------------------
-
+
public JDBCLoadEntityCommand(JDBCCommandFactory factory)
{
super(factory, "Load");
-
+
// Select SQL
String sql = "SELECT ";
-
+
Iterator it = metaInfo.getCMPFieldInfos();
boolean first = true;
-
+
while (it.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)it.next();
-
+
if (fieldInfo.isEJBReference())
{
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
-
+
for (int i = 0; i < pkFields.length; i++)
{
sql += (first ? "" : ",") +
@@ -74,15 +74,15 @@
first = false;
}
}
-
+
sql += " FROM " + metaInfo.getTableName() +
" WHERE " + getPkColumnWhereList();
-
+
setSQL(sql);
}
-
+
// JPMLoadEntityCommand implementation ---------------------------
-
+
public void execute(EntityEnterpriseContext ctx)
throws RemoteException
{
@@ -97,35 +97,34 @@
}
}
}
-
+
// JDBCQueryCommand overrides ------------------------------------
-
- protected void setParameters(PreparedStatement stmt, Object argOrArgs)
+
+ protected void setParameters(PreparedStatement stmt, Object argOrArgs)
throws Exception
{
EntityEnterpriseContext ctx = (EntityEnterpriseContext)argOrArgs;
-
+
setPrimaryKeyParameters(stmt, 1, ctx.getId());
}
-
+
protected Object handleResult(ResultSet rs, Object argOrArgs) throws Exception
{
EntityEnterpriseContext ctx = (EntityEnterpriseContext)argOrArgs;
-
+
if (!rs.next())
{
throw new NoSuchObjectException("Entity "+ctx.getId()+" not found");
}
-
+
// Set values
int idx = 1;
-
+
Iterator iter = metaInfo.getCMPFieldInfos();
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
- int jdbcType = fieldInfo.getJDBCType();
-
+
if (fieldInfo.isEJBReference())
{
// Create pk
@@ -139,9 +138,9 @@
Field[] fields = pk.getClass().getFields();
for(int j = 0; j < fields.length; j++)
{
- Object val = getResultObject(rs, idx++, jdbcType);
+ Object val = getResultObject(rs, idx++, fields[j].getType());
fields[j].set(pk, val);
-
+
if (debug)
{
log.debug("Referenced pk field:" + val);
@@ -150,21 +149,21 @@
} else
{
// Primitive key
- pk = getResultObject(rs, idx++, jdbcType);
-
+ pk = getResultObject(rs, idx++, fieldInfo.getField().getType());
+
if (debug)
{
log.debug("Referenced pk:" + pk);
}
}
-
+
// Find referenced entity
try
{
Object home = factory.getJavaCtx().lookup(fieldInfo.getSQLType());
Method[] homeMethods = home.getClass().getMethods();
Method finder = null;
-
+
// We have to locate fBPK iteratively since we don't
// really know the pk-class
for (int j = 0; j < homeMethods.length; j++)
@@ -175,16 +174,16 @@
break;
}
}
-
+
if (finder == null)
{
throw new NoSuchMethodException(
"FindByPrimaryKey method not found in home interface");
}
-
+
log.debug("PK=" + pk);
Object ref = finder.invoke(home, new Object[] { pk });
-
+
// Set found entity
setCMPFieldValue(ctx.getInstance(), fieldInfo, ref);
} catch (Exception e)
@@ -194,30 +193,30 @@
} else
{
// Load primitive
-
+
// TODO: this probably needs to be fixed for BLOB's etc.
- setCMPFieldValue(ctx.getInstance(),
- fieldInfo,
- getResultObject(rs, idx++, jdbcType));
+ setCMPFieldValue(ctx.getInstance(),
+ fieldInfo,
+ getResultObject(rs, idx++,
fieldInfo.getField().getType()));
}
}
-
+
// Store state to be able to do tuned updates
JAWSPersistenceManager.PersistenceContext pCtx =
(JAWSPersistenceManager.PersistenceContext)ctx.getPersistenceContext();
if (metaInfo.isReadOnly()) pCtx.lastRead = System.currentTimeMillis();
pCtx.state = getState(ctx);
-
+
return null;
}
-
+
// Protected -----------------------------------------------------
-
+
protected boolean isTimedOut(EntityEnterpriseContext ctx)
{
JAWSPersistenceManager.PersistenceContext pCtx =
(JAWSPersistenceManager.PersistenceContext)ctx.getPersistenceContext();
-
+
return (System.currentTimeMillis() - pCtx.lastRead) >
metaInfo.getReadOnlyTimeOut();
}
}