[jboss-svn-commits] JBL Code SVN: r29278 - in labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src: main/java/uk/ac/ncl/sdia/a8905943/handle and 9 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Sep 9 12:36:03 EDT 2009
Author: whitingjr
Date: 2009-09-09 12:36:03 -0400 (Wed, 09 Sep 2009)
New Revision: 29278
Added:
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/IdentityFieldWriteParameter.java
Modified:
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/FieldUtils.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/HandleUtils.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractFieldParameter.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/jdbc/STMConnection.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/xa/STMXAConnectionImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldReadParameter.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldWriteParameter.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/META-INF/jboss-aop.xml
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/log4j.xml
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java
Log:
Added test cases. Added funtionality to EntityManager.
Started to add modification persistence of model store.
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -6,19 +6,19 @@
*/
package uk.ac.ncl.sdia.a8905943.entitymanager;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
+import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.Query;
import javax.persistence.spi.PersistenceUnitTransactionType;
-import javax.transaction.Synchronization;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.log4j.Logger;
@@ -26,358 +26,440 @@
import uk.ac.ncl.sdia.a8905943.factory.STMFactory;
import uk.ac.ncl.sdia.a8905943.handle.FieldUtils;
+import uk.ac.ncl.sdia.a8905943.handle.HandleUtils;
import uk.ac.ncl.sdia.a8905943.handle.exception.FieldNotFoundException;
import uk.ac.ncl.sdia.a8905943.persistence.jdbc.STMConnection;
+import uk.ac.ncl.sdia.a8905943.stm.field.FieldWriteParameter;
+import uk.ac.ncl.sdia.a8905943.stm.field.IdentityFieldWriteParameter;
+import uk.ac.ncl.sdia.a8905943.stm.query.STMQueryImpl;
-final class STMEntityManagerImpl implements EntityManager {
- private PersistenceUnitTransactionType type;
+final class STMEntityManagerImpl implements EntityManager
+{
+ private PersistenceUnitTransactionType type;
- // this reference is a wrapped object
- protected Connection connection;
+ // this reference is a wrapped object
+ protected Connection connection;
- private static final Logger logger = Logger
- .getLogger(STMEntityManagerImpl.class);
+ private static final Logger logger = Logger
+ .getLogger(STMEntityManagerImpl.class);
- private boolean isOpen = false;
+ private boolean isOpen = false;
- @Override
- public void clear() {
- STMFactory.getFactoryInstance().deallocate();
- }
+ @Override
+ public void clear()
+ {
+ STMFactory.getFactoryInstance().deallocate();
+ }
- @Override
- public void close() {
- /*
- * get the currently active transaction on this thread, register a
- * synchronization to close the Connection object.
- */
- if (logger.isDebugEnabled()) {
- logger.debug("STMEntityManagerImpl.close called.");
- }
+ @Override
+ public void close()
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("STMEntityManagerImpl.close called.");
+ }
- // TransactionManager transactionManager =
- // ServiceLocator.findLocalPersonManager();
- try {
- this.connection.close();
- /*
- * Transaction transaction = transactionManager.getTransaction(); if
- * (null != transaction) { transaction.registerSynchronization(new
- * CloseSTMEM()); }
- */
- }
- /*
- * catch (SystemException se) { logger .error(
- * "Problem occured when registering a synchronization to close the Connection after the Transaction has completed."
- * , se); throw new RuntimeException(se); } catch (RollbackException re)
- * {
- * logger.error("Could not register a Synchronization for STMEntityManager"
- * ); throw new RuntimeException(re); }
- */
- catch (SQLException sqle) {
- logger
- .error("SQLException occured when closing the connection object when, the EM is closed.");
- throw new RuntimeException(sqle);
- }
- STMFactory.getFactoryInstance().deallocate();
+ try
+ {
+ this.connection.close();
+ }
+ catch (SQLException sqle)
+ {
+ logger
+ .error("SQLException occured when closing the connection object when, the EM is closed.");
+ throw new RuntimeException(sqle);
+ }
+ STMFactory.getFactoryInstance().deallocate();
- this.isOpen = false;
- }
+ this.isOpen = false;
+ }
- /**
- * This method will use the entity class details and the unique identity to
- * verify if the entity exists in the model store.
- */
- @Override
- public boolean contains(Object entity) {// check the memory store for the
- // presence of the managed entity
- boolean returnValue = false;
- String entityFQCN = null;
- Long entityUniqueIdentity = null;
+ /**
+ * This method will use the entity class details and the unique identity to
+ * verify if the entity exists in the model store.
+ */
+ @Override
+ public boolean contains(Object entity)
+ {// check the memory store for the
+ // presence of the managed entity
+ detectectClosedConnection();
+ boolean returnValue = false;
+ String entityFQCN = null;
+ Long entityUniqueIdentity = null;
- if (null != entity) {
- entityFQCN = entity.getClass().getName();
- FieldUtils fieldUtils = new FieldUtils();
- try
- {
- Field idField = fieldUtils.findIdField(entity.getClass());
- entityUniqueIdentity = fieldUtils.getValue(idField, entity);
- JXPathContext context = JXPathContext.newContext(getSTMConnection().getSTM());
- context.getVariables().declareVariable("entityType", entityFQCN);
- context.getVariables().declareVariable("identityField", idField.getName());
- context.getVariables().declareVariable("identityValue", entityUniqueIdentity);
- returnValue = (null == context.getValue("model/$entityType[$identityField=$identityValue]") ? Boolean.FALSE.booleanValue(): Boolean.TRUE.booleanValue());
- }
- catch (FieldNotFoundException fnfe)
- {
- this.logger.error(fnfe.getMessage(), fnfe);
- }
- }
- return returnValue;
- }
+ if (null != entity)
+ {
+ entityFQCN = entity.getClass().getName();
+ FieldUtils fieldUtils = new FieldUtils();
+ try
+ {
+ Field idField = fieldUtils.findIdField(entity.getClass());
+ entityUniqueIdentity = fieldUtils.getValue(idField, entity);
+
+ /* Check the field store for the identity field first, doing this detects if the entity has been removed beforehand. The model store*/
+
+ JXPathContext context = JXPathContext.newContext(getSTMConnection()
+ .getSTM());
+ context.setLenient(true);
+ StringBuffer query = new StringBuffer();
+ query.append("model/").append(entityFQCN).append("[");
+ query.append(idField.getName()).append("=$identityValue]");
+ context.getVariables().declareVariable("identityValue",
+ entityUniqueIdentity);
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("executing query [" + query.toString() + "]");
+ }
+ returnValue = (null == context.getValue(query.toString()) ? Boolean.FALSE
+ .booleanValue()
+ : Boolean.TRUE.booleanValue());
+ }
+ catch (FieldNotFoundException fnfe)
+ {
+ logger.error(fnfe.getMessage(), fnfe);
+ }
+ }
+ return returnValue;
+ }
- @Override
- public Query createNamedQuery(String name) {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
- return null;
- }
+ @Override
+ public Query createNamedQuery(String name)
+ {
+ if (true)
+ {
+ throw new UnsupportedOperationException(
+ "Unsupported operation createNamedQuery(String)");
+ }
+ return null;
+ }
- @Override
- public Query createNativeQuery(String sqlString) {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
+ @Override
+ public Query createNativeQuery(String sqlString)
+ {
+ if (true)
+ {
+ throw new UnsupportedOperationException(
+ "Unsupported operation createNamedQuery(String)");
+ }
- return null;
- }
+ return null;
+ }
- @Override
- public Query createNativeQuery(String sqlString, Class resultClass) {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
- return null;
- }
+ @Override
+ public Query createNativeQuery(String sqlString, Class resultClass)
+ {
+ if (true)
+ {
+ throw new UnsupportedOperationException(
+ "Unsupported operation createNamedQuery(String)");
+ }
+ return null;
+ }
- @Override
- public Query createNativeQuery(String sqlString, String resultSetMapping) {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
- return null;
- }
+ @Override
+ public Query createNativeQuery(String sqlString, String resultSetMapping)
+ {
+ if (true)
+ {
+ throw new UnsupportedOperationException(
+ "Unsupported operation createNamedQuery(String)");
+ }
+ return null;
+ }
- @Override
- public Query createQuery(String qlString) {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
- return null;
- }
+ /**
+ * This method returns a Query object to query the STM data store.
+ */
+ @Override
+ public Query createQuery(String qlString) throws IllegalArgumentException
+ {
+ detectectClosedConnection();
+ Query returnValue = null;
+ if (null != qlString)
+ {
+ JXPathContext context = JXPathContext.newContext(this
+ .getSTMConnection().getSTM());
+ returnValue = new STMQueryImpl(context, qlString);
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "The query string provided is null.");
+ }
+ return returnValue;
+ }
- @Override
- /**
- * To call this method the entity object is expected to follow this contract.
- * Entity has one constructor that is public, contains only one field and is of
- * type {@link java.lang.Long}.
- * The entity class is annotated with the STMEntity annotation.
- * This method does not hit the STM system and only uses reflection to create
- * an instance of the entity.
- */
- public <T> T find(Class<T> entityClass, Object primaryKey) {
- if (logger.isDebugEnabled()) {
- logger.debug("STMEntityManagerImpl.find called.");
- }
- T returnValue = null;
- // check if the class has been annotated using the STM annotations.
- boolean isstmEntity = false;
+ @SuppressWarnings("unchecked")
+ @Override
+ /**
+ * To call this method the entity object is expected to follow this contract.
+ * Entity has one constructor that is public, contains only one field and is of
+ * type {@link java.lang.Long}.
+ * The entity class is annotated with the STMEntity annotation.
+ * This method does not hit the STM system and only uses reflection to create
+ * an instance of the entity.
+ */
+ public <T> T find(Class<T> entityClass, Object primaryKey)
+ {
+ detectectClosedConnection();
+ T returnValue = null;
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("STMEntityManagerImpl.find called.");
+ }
- /**
- * This no longer works, using AOP means the reference given is an
- * instance of some proxy class.
- */
- /*
- * for (Annotation annotation : entityClass.getAnnotations()) { if
- * (annotation instanceof STMEntity) { isstmEntity = true; } }
- */
- // TODO: jrw replace this implementation, should go into STM and check
- // the model store for existence.
- isstmEntity = true;
- if (isstmEntity) {// STM entity class, create an instance
- try {
- Constructor<T> targetConstructor = entityClass
- .getConstructor(Long.class);
- returnValue = targetConstructor.newInstance(primaryKey);
- } catch (InstantiationException ie) {
- logger
- .error(
- "Problem occured when creating an instance of an entity object.",
- ie);
- } catch (IllegalAccessException iae) {
- logger
- .error(
- "Problem occured when creating an entity, constructor is expected to be public.",
- iae);
- } catch (NoSuchMethodException nsme) {
- logger
- .error(
- "Expected constructor does not exist, please create a public constructor taking the primary key field only.",
- nsme);
- if (logger.isDebugEnabled()) {
- logger.debug(log(entityClass));
- for (Constructor constructor : entityClass
- .getConstructors()) {
- logger.debug("Constructor ["
- + constructor.toGenericString() + "]");
- }
- }
- } catch (IllegalArgumentException illae) {
- logger.error(
- "Expected primary key type is expected to be Long.",
- illae);
- } catch (InvocationTargetException e) {
- logger
- .error(
- "Something went wrong when getting creating an entity object",
- e);
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug(log(entityClass));
- }
- }
- return returnValue;
- }
+ detectectClosedConnection();
- @Override
- public void flush() {
- if (true) {
- throw new UnsupportedOperationException(
- "Unsupported operation createNamedQuery(String)");
- }
- }
+ FieldUtils fieldUtils = new FieldUtils();
+ try
+ {
+ Field idField = fieldUtils.findIdField(entityClass);
+ StringBuffer queryStatement = new StringBuffer();
- public String log(Class entityClass) {
- String name = entityClass.getName();
- name = name.substring(name.lastIndexOf(".") + 1) + ".class";
- return name + " loaded from " + entityClass.getResource(name);
- }
+ queryStatement.append("model/").append(entityClass.getName()).append(
+ "[").append(idField.getName());
+ queryStatement.append("=$identityValue]");
+ Query query = this.createQuery(queryStatement.toString());
+ query.setParameter("identityValue", primaryKey);
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Executing query [" + queryStatement.toString()
+ + "] with primary key value [" + primaryKey + "].");
+ }
+ returnValue = (T) query.getSingleResult();
+ }
+ catch (FieldNotFoundException fnfe)
+ {
+ logger.error("Identity field not found when finding entity.", fnfe);
+ throw new IllegalArgumentException(fnfe.getMessage());
+ }
- @Override
- public Object getDelegate() {
- // FIXME getDelegate
- return null;
- }
+ return returnValue;
+ }
- @Override
- public FlushModeType getFlushMode() {
- // FIXME getFlushMode
- return null;
- }
+ @Override
+ public void flush()
+ {
+ if (true)
+ {
+ throw new UnsupportedOperationException(
+ "Unsupported operation createNamedQuery(String)");
+ }
+ }
- @Override
- public <T> T getReference(Class<T> entityClass, Object primaryKey) {
- // FIXME getReference
- return null;
- }
+ public String log(Class entityClass)
+ {
+ String name = entityClass.getName();
+ name = name.substring(name.lastIndexOf(".") + 1) + ".class";
+ return name + " loaded from " + entityClass.getResource(name);
+ }
- @Override
- public EntityTransaction getTransaction() {
- if (PersistenceUnitTransactionType.JTA == this.type) {
- throw new IllegalStateException(
- "An EntityTransaction used bye EXTENDED entity managers is not allowed for the JTA transaction types.");
- }
- return null;
- }
+ @Override
+ public Object getDelegate()
+ {
+ detectectClosedConnection();
+ // FIXME getDelegate
+ return null;
+ }
- @Override
- public boolean isOpen() {
- return this.isOpen;
- }
+ @Override
+ public FlushModeType getFlushMode()
+ {
+ detectectClosedConnection();
+ // FIXME getFlushMode
+ return null;
+ }
- @Override
- public void joinTransaction() {
- // FIXME joinTransaction
+ @Override
+ public <T> T getReference(Class<T> entityClass, Object primaryKey)
+ {
+ detectectClosedConnection();
+ return find(entityClass, primaryKey);
+ }
- }
+ @Override
+ public EntityTransaction getTransaction()
+ {
+ if (PersistenceUnitTransactionType.JTA == this.type)
+ {
+ throw new IllegalStateException(
+ "An EntityTransaction used bye EXTENDED entity managers is not allowed for the JTA transaction types.");
+ }
+ return null;
+ }
- @Override
- public void lock(Object entity, LockModeType lockMode) {
- // FIXME lock
+ @Override
+ public boolean isOpen()
+ {
+ return this.isOpen;
+ }
- }
+ @Override
+ public void joinTransaction()
+ {
+ detectectClosedConnection();
+ // FIXME joinTransaction
- @Override
- public <T> T merge(T entity) {
- // FIXME merge
- return null;
- }
+ }
- @Override
- public void persist(Object entity) {
- // FIXME persist
+ @Override
+ public void lock(Object entity, LockModeType lockMode)
+ {
+ detectectClosedConnection();
+ // FIXME lock
- }
+ }
- @Override
- public void refresh(Object entity) {
- // FIXME refresh
+ @Override
+ public <T> T merge(T entity)
+ {
+ detectectClosedConnection();
+ // FIXME merge
+ return null;
+ }
- }
+ @Override
+ public void persist(Object entity)
+ throws EntityExistsException
+ {
+ detectectClosedConnection();
+ FieldUtils fieldUtils = new FieldUtils();
+ try
+ {
+ Field identityField = fieldUtils.findIdField(entity.getClass());
+ Long id = fieldUtils.getValue(identityField, entity );
+ if (this.contains(entity))
+ {
+ throw new EntityExistsException("Attempt to persist an entity which already exists in the system with unique identity.");
+ }
+ // TODO: jrw, think about what has been already persisted considering an entity is directly "wired" into the persistence system.
+ }
+ catch (FieldNotFoundException fnfe)
+ {
+ logger.error("Error occured when attempting to persist an entity.", fnfe);
+ }
+ }
- @Override
- public void remove(Object entity) {
- // FIXME remove
+ @Override
+ public void refresh(Object entity)
+ {
+ detectectClosedConnection();
+ //TODO: jrw, Should anything be necessary here, any changes made by the application are already part of the transation
- }
+ }
- @Override
- public void setFlushMode(FlushModeType flushMode) {
- // FIXME setFlushMode
+ @Override
+ public void remove(Object entity)
+ {
+ detectectClosedConnection();
+ //TODO: jrw: complete method, find all the setter methods of this entity. loop through and set each to null. Do not notify the model store leave this till committment.
+ /* Nullify all the entity fields. identity is excluded */
+ Object nullref =null;
+ FieldUtils fieldUtils = new FieldUtils();
+ for (Method method : fieldUtils.retrieveTransactionalSetterMethods(entity.getClass()))
+ {
+ try
+ {
+ method.invoke(entity, nullref);
+ }
+ catch (InvocationTargetException ite)
+ {
+ logger.error("Error occurred when invoking each write method on entity.", ite);
+ throw new RuntimeException("Problem occurred invoking method to remove it's contents. Potential cleanup operation required.");
+ }
+ catch (IllegalAccessException iae)
+ {
+ logger.error("Error occurred when invoking each write method on entity.", iae);
+ throw new RuntimeException("Problem occured accessing method to remove the field from field store. Potential cleanup operation required.");
+ }
+ }
+ try
+ {/* Now nullify the identity field */
+ Field identityField = fieldUtils.findIdField(entity.getClass());
+ Long identity = fieldUtils.getValue(identityField, entity);
+ long fieldStoreHandle = new HandleUtils().getHandle(entity.getClass(), identity, identityField.getName());
+
+ IdentityFieldWriteParameter write = new IdentityFieldWriteParameter(fieldStoreHandle, nullref, identity);
+ this.getSTMConnection().getSTM().write(write);
+ }
+ catch (FieldNotFoundException fnfe)
+ {
+ logger.error(fnfe.getMessage());
+ }
+
+
+ }
- }
+ @Override
+ public void setFlushMode(FlushModeType flushMode)
+ {
+ detectectClosedConnection();
+ // FIXME setFlushMode
- private STMEntityManagerImpl() {
- }
+ }
- public STMEntityManagerImpl(Connection connection) {
- this();
- this.connection = connection;
- STMFactory.getFactoryInstance().allocate(getSTMConnection().getSTM());
- }
+ private STMEntityManagerImpl()
+ {
+ }
- public STMConnection getSTMConnection() {
- STMConnection returnValue = null;
- if (null != this.connection) {
- try {
- returnValue = (STMConnection) ((WrappedConnection) this.connection)
- .getUnderlyingConnection();
- } catch (SQLException sqle) {
- logger.error(sqle);
- throw new RuntimeException(sqle);
- } catch (ClassCastException cce) {// check to see if this connection
- // is a basic STMConnection,
- // used in unit testing
- if (this.connection instanceof STMConnection) {
- returnValue = (STMConnection) this.connection;
- }
- }
- }
- return returnValue;
- }
+ public STMEntityManagerImpl(Connection connection)
+ {
+ this();
+ this.connection = connection;
+ STMFactory.getFactoryInstance().allocate(getSTMConnection().getSTM());
+ }
- public void setConnection(Connection connection) {
- this.connection = connection;
- }
+ public STMConnection getSTMConnection()
+ {
+ STMConnection returnValue = null;
+ if (null != this.connection)
+ {
+ try
+ {
+ returnValue = (STMConnection) ((WrappedConnection) this.connection)
+ .getUnderlyingConnection();
+ }
+ catch (SQLException sqle)
+ {
+ logger.error(sqle);
+ throw new RuntimeException(sqle);
+ }
+ catch (ClassCastException cce)
+ {// check to see if this connection
+ // is a basic STMConnection,
+ // used in unit testing
+ if (this.connection instanceof STMConnection)
+ {
+ returnValue = (STMConnection) this.connection;
+ }
+ }
+ }
+ return returnValue;
+ }
- private class CloseSTMEM implements Synchronization {
- private final Logger logger = Logger.getLogger(CloseSTMEM.class);
+ public void setConnection(Connection connection)
+ {
+ this.connection = connection;
+ }
- @Override
- public void beforeCompletion() {
- // do nothing
- }
-
- @Override
- public void afterCompletion(int status) {
- /*
- * Check to see if the Connection has been release back to the pool.
- */
- try {
- STMFactory.getFactoryInstance().deallocate();
- if (!connection.isClosed()) {
- connection.close();// release connection back into container
- // pool
- }
- } catch (SQLException e) {
- logger.error("Error", e);
- }
- }
- }
+ private void detectectClosedConnection() throws IllegalStateException
+ {
+ try
+ {
+ if (this.getSTMConnection().isClosed())
+ {
+ throw new IllegalStateException(
+ "The connection associated with this EntityManager has been closed.");
+ }
+ }
+ catch (SQLException sqle)
+ {
+ logger
+ .error(
+ "Underlying database connection threw a SQLException when attempting to detect if the connection was closed.",
+ sqle);
+ throw new IllegalStateException(
+ "The underlying connection threw a SQLException.");
+ }
+ }
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/FieldUtils.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/FieldUtils.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/FieldUtils.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -8,12 +8,16 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
import javax.persistence.Id;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.log4j.Logger;
+import uk.ac.ncl.sdia.a8905943.aspects.annotation.STMWriteable;
import uk.ac.ncl.sdia.a8905943.handle.exception.FieldNotFoundException;
public class FieldUtils
@@ -62,4 +66,20 @@
}
return returnValue;
}
+
+ public List<Method> retrieveTransactionalSetterMethods(Class entityClass)
+ {
+ List<Method> returnValue = new ArrayList<Method>();
+ for (Method method : entityClass.getDeclaredMethods())
+ {
+ for (Annotation annotation: method.getAnnotations())
+ {
+ if (annotation instanceof STMWriteable)
+ {
+ returnValue.add(method);
+ }
+ }
+ }
+ return returnValue;
+ }
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/HandleUtils.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/HandleUtils.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/handle/HandleUtils.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -12,7 +12,9 @@
public class HandleUtils
{
-
+ /**
+ * @deprecated
+ */
public long getHandle(Class entity, String id, Field field )
{
return new HashCodeBuilder(17, 37).append(entity.getName()).append(id).append(field.getName()).toHashCode();
@@ -21,10 +23,16 @@
{
return new HashCodeBuilder(17, 37).append(entity.getName()).append(id).append(fieldName).toHashCode();
}
+ /**
+ * @deprecated
+ */
public long getFieldHandle(Class entity, String entityId, int fieldIndex)
{
return new HashCodeBuilder(17, 37).append(entity.getName()).append(entityId).append(fieldIndex).toHashCode();
}
+ /**
+ * @deprecated
+ */
public long getHandle(Class entity, int fieldIndex)
{
return new HashCodeBuilder(17, 37).append(entity.getName()).append(fieldIndex).toHashCode();
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -9,8 +9,10 @@
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import javax.transaction.Status;
@@ -36,6 +38,12 @@
protected volatile int status = Status.STATUS_NO_TRANSACTION;
protected final Map<Long, TransactedObjectReference> deferredReads = new HashMap<Long, TransactedObjectReference>();
protected final Map<Long, TransactedObjectReference> deferredWrites = new HashMap<Long, TransactedObjectReference>();
+ protected final Set<Long> deletedEntities = new HashSet<Long>();
+ public Set<Long> getDeletedEntities()
+ {
+ return deletedEntities;
+ }
+
private final CountDownLatch phaseTwoTerminated = new CountDownLatch(1);
/**
@@ -95,6 +103,7 @@
{
fieldWrite.setWrites(this.deferredWrites);
fieldWrite.setVersion(this.version);
+ fieldWrite.setWrittenIdentityFields(this.deletedEntities);
return this.isolation.write(fieldWrite);
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractFieldParameter.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractFieldParameter.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractFieldParameter.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -10,18 +10,28 @@
import uk.ac.ncl.sdia.a8905943.stm.object.TransactedObjectReference;
-public class AbstractFieldParameter
+public abstract class AbstractFieldParameter
{
protected Map<Long, TransactedObjectReference> objectStore;
protected long handle;
protected Map<Long, TransactedObjectReference> writes;
private long version;
private boolean isTransactional = true;// this should be turned off for queries ?
+ private Long identity;
+ public Long getIdentity()
+ {
+ return identity;
+ }
+ public void setIdentity(Long identity)
+ {
+ this.identity = identity;
+ }
public AbstractFieldParameter()
{
super();
}
+ public abstract boolean isIdentityField();
public Map<Long, TransactedObjectReference> getObjectStore()
{
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -77,6 +77,10 @@
fieldReference = new TransactedObjectReference(fieldWrite.getHandle(), fieldWrite.getNewObject(), fieldWrite.getVersion());
fieldWrite.getWrites().put(fieldWrite.getHandle(), fieldReference);
}
+ if (null == fieldWrite.getNewObject() && fieldWrite.isIdentityField())
+ {
+ fieldWrite.getWrittenIdentityFields().add(fieldWrite.getIdentity());
+ }
returnValue = Boolean.TRUE;
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/jdbc/STMConnection.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/jdbc/STMConnection.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/jdbc/STMConnection.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -40,7 +40,7 @@
{
private static final Logger logger = Logger.getLogger(STMConnection.class);
private final boolean autoCommit = false;
- private boolean isActive = false;
+ private boolean isActive = true;
private final STMXAConnectionImpl xaConnection ;
@Override
@@ -414,4 +414,9 @@
return this.xaConnection.getSTM();
}
+ public void setActive(boolean isActiveState)
+ {
+ this.isActive = isActiveState;
+ }
+
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/xa/STMXAConnectionImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/xa/STMXAConnectionImpl.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/persistence/xa/STMXAConnectionImpl.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -96,7 +96,7 @@
this.logicalConnection.compareAndSet(null, new STMConnection(this));
}
returnValue = this.logicalConnection.get();
-
+ returnValue.setActive(true);
return returnValue;
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldReadParameter.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldReadParameter.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldReadParameter.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -38,4 +38,10 @@
{
this.handle = handle;
}
+
+ @Override
+ public boolean isIdentityField()
+ {
+ return false;
+ }
}
\ No newline at end of file
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldWriteParameter.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldWriteParameter.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/FieldWriteParameter.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -6,13 +6,24 @@
*/
package uk.ac.ncl.sdia.a8905943.stm.field;
+import java.util.Set;
+
import uk.ac.ncl.sdia.a8905943.isolation.AbstractFieldParameter;
public class FieldWriteParameter extends AbstractFieldParameter
{
private Object newObject;
+ private Set<Long> writtenIdentityFields;
+ public Set<Long> getWrittenIdentityFields()
+ {
+ return writtenIdentityFields;
+ }
+ public void setWrittenIdentityFields(Set<Long> writtenIdentityFields)
+ {
+ this.writtenIdentityFields = writtenIdentityFields;
+ }
public Object getNewObject()
{
return newObject;
@@ -26,4 +37,9 @@
this.handle = handle;
this.newObject = newObject;
}
+ @Override
+ public boolean isIdentityField()
+ {
+ return false;
+ }
}
\ No newline at end of file
Added: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/IdentityFieldWriteParameter.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/IdentityFieldWriteParameter.java (rev 0)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/IdentityFieldWriteParameter.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -0,0 +1,39 @@
+ /*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package uk.ac.ncl.sdia.a8905943.stm.field;
+
+public final class IdentityFieldWriteParameter extends FieldWriteParameter
+{
+ @Override
+ public boolean isIdentityField()
+ {
+ return true;
+ }
+
+ public IdentityFieldWriteParameter(long handle, Object newObject, Long identity)
+ {
+ super(handle, newObject);
+ setIdentity(identity);
+ }
+
+}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -78,10 +78,11 @@
/* Depending on how far this transaction has progressed need to undo locks and clear
* collection objects. */
logger.info("STMTransaction has been called to abort the transaction.");
- try
+
+ transaction.setStatus(Status.STATUS_MARKED_ROLLBACK);
+ for (TransactedObjectReference reference : transaction.getDeferredWrites().values())
{
- transaction.setStatus(Status.STATUS_MARKED_ROLLBACK);
- for (TransactedObjectReference reference : transaction.getDeferredWrites().values())
+ try
{
TransactedObjectReference sharedReference = fieldMemory.get(reference.getLookupIdentity());
if (null != sharedReference)
@@ -96,16 +97,17 @@
{
logger.error("Problem occured, prepared lock is not held by current thread. Interleaving threads not working properly.");
}
+
}
+ }
+ catch (Exception e)
+ {
+ logger.error(e.getMessage(), e);
}
logger.info("STMTransaction has finished releasing all the locks aquired during prepare phase.");
transaction.setStatus(Status.STATUS_ROLLEDBACK);
transaction.getPhaseTwoTerminated().countDown();
}
- catch (Exception e)
- {
- logger.error(e.getMessage(), e);
- }
}
/**
* The purpose of this method is to lock all resources needed by the transaction. Need to keep a list of the
@@ -280,6 +282,8 @@
/* don't really want to substitute the shared version with the deferred write.
* should update values and use the count down latch to notify resource available. */
// go ahead and replace all the values inside the shared transacted reference.
+
+ //TODO: jrw refactor the update mechanism. Needs to be architected to support complex update mechanisms such as modifying the model store as well as removing something from field store.
sharedReference.setValue(deferredWrite.getValue());
sharedReference.setVersion(deferredWrite.getVersion());
sharedReference.setPreparedVersion(null);
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/META-INF/jboss-aop.xml
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/META-INF/jboss-aop.xml 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/META-INF/jboss-aop.xml 2009-09-09 16:36:03 UTC (rev 29278)
@@ -5,21 +5,7 @@
<aspect name="stminjectionaspect"
class="uk.ac.ncl.sdia.a8905943.aspects.STMInjectionAspect" />
- <!-- bind
- pointcut="execution(* *->@uk.ac.ncl.sdia.a8905943.aspects.annotation.STMWriteable(..))">
- <advice name="stmwrite" aspect="stmwriteaspect" />
- </bind>
- <bind
- pointcut="execution(* *->@uk.ac.ncl.sdia.a8905943.aspects.annotation.STMReadable(..))">
- <advice name="stmread" aspect="stmreadaspect" />
- </bind>
-
- <bind
- pointcut="field(uk.ac.ncl.sdia.a8905943.stm.STM *->@uk.ac.ncl.sdia.a8905943.stm.annotation.InjectedSTM )">
- <advice name="access" aspect="stminjectionaspect" />
- </bind-->
-
<bind
pointcut="execution(* *->@uk.ac.ncl.sdia.a8905943.aspects.annotation.STMWriteable(..))">
<advice name="stmwrite" aspect="stmwriteaspect" />
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/log4j.xml
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/log4j.xml 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/resources/log4j.xml 2009-09-09 16:36:03 UTC (rev 29278)
@@ -37,7 +37,7 @@
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
- <param name="Threshold" value="DEBUG" />
+ <param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
@@ -290,7 +290,7 @@
<!-- ======================= -->
<root>
- <priority value="DEBUG" />
+ <priority value="TRACE" />
<appender-ref ref="CONSOLE" />
</root>
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java 2009-09-09 14:48:32 UTC (rev 29277)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java 2009-09-09 16:36:03 UTC (rev 29278)
@@ -1,12 +1,17 @@
package uk.ac.ncl.sdia.a8905943.entitymanager;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import javax.persistence.EntityExistsException;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+import javax.persistence.Query;
+
import junit.framework.Assert;
+import org.apache.commons.jxpath.JXPathContext;
import org.junit.Test;
import uk.ac.ncl.sdia.a8905943.model.LeccyCar;
@@ -15,34 +20,167 @@
import uk.ac.ncl.sdia.a8905943.persistence.xa.STMXADatasourceImpl;
import uk.ac.ncl.sdia.a8905943.stm.AbstractUnitT;
-public class TestSTMEntityManagerImpl extends AbstractUnitT
-{
- private STMEntityManagerImpl entityManager ;
+public class TestSTMEntityManagerImpl extends AbstractUnitT {
+ private STMEntityManagerImpl entityManager;
+
/**
* This test case puts a known entity into the persistent store. Calls the
- * EntityManager to see if the entity can be found.
+ * EntityManager to see if the entity can be found.
*/
@Test
- public void testCheckEntityFound()
+ public void testCheckContainsMethodWorks() {
+ Map<String, List<Object>> modelStore = this.stm.getModel();
+ Long carId = new Long(1);
+ LeccyCar car = new LeccyCar(carId);
+ List<Object> carList = new ArrayList<Object>();
+ carList.add(car);
+ String carFQCN = "uk.ac.ncl.sdia.a8905943.model.LeccyCar";
+ Assert.assertEquals(carFQCN, car.getClass().getName());
+ modelStore.put(car.getClass().getName(), carList);
+
+ Assert.assertNotNull(this.entityManager);
+ Assert.assertTrue(this.entityManager.contains(car));
+
+ LeccyCar hydrogenCar = new LeccyCar(4l);
+ Assert.assertFalse(this.entityManager.contains(hydrogenCar));
+ }
+
+ @Test
+ public void testCheckCheckForNonExistingEntityNoException() {
+ LeccyCar hydrogenCar = new LeccyCar(4l);
+ Assert.assertFalse(this.entityManager.contains(hydrogenCar));
+ }
+
+ /**
+ * This test checks a single result query works.
+ */
+ @Test
+ public void testCheckSingleResultQueryWorks() {
+ Map<String, List<Object>> modelStore = this.stm.getModel();
+ Long carId = new Long(1);
+ LeccyCar car = new LeccyCar(carId);
+ List<Object> carList = new ArrayList<Object>();
+ carList.add(car);
+ String carFQCN = "uk.ac.ncl.sdia.a8905943.model.LeccyCar";
+ Assert.assertEquals(carFQCN, car.getClass().getName());
+ modelStore.put(car.getClass().getName(), carList);
+
+ Assert.assertNotNull(this.entityManager);
+ Query query = this.entityManager.createQuery("model/"+carFQCN);
+ Object entity = query.getSingleResult();
+ Assert.assertNotNull(entity);
+ Assert.assertNotNull(entity.getClass());
+ Assert.assertEquals(entity.getClass(), car.getClass());
+ LeccyCar resultEntity = (LeccyCar)entity;
+ Assert.assertEquals(car.getId(), resultEntity.getId());
+ }
+ /**
+ * Check the Query object throws an exception.
+ *
+ */
+ @Test (expected=NoResultException.class)
+ public void testCheckSingleResultQueryThrowsNoResultException()
{
+ Query query = this.entityManager.createQuery("model/duff");
+ query.getSingleResult();
+ }
+ /**
+ * check multiple entities in result set throws an exception
+ */
+ @Test (expected=NonUniqueResultException.class)
+ public void testCheckSingleResultQueryThrowsNonUniqueException()
+ {
Map<String, List<Object>> modelStore = this.stm.getModel();
Long carId = new Long(1);
LeccyCar car = new LeccyCar(carId);
List<Object> carList = new ArrayList<Object>();
carList.add(car);
+ carList.add(new LeccyCar(new Long(2)));
String carFQCN = "uk.ac.ncl.sdia.a8905943.model.LeccyCar";
Assert.assertEquals(carFQCN, car.getClass().getName());
modelStore.put(car.getClass().getName(), carList);
Assert.assertNotNull(this.entityManager);
- Assert.assertTrue(this.entityManager.contains(car));
+ Query query = this.entityManager.createQuery("model/"+carFQCN);
+ Object entity = query.getSingleResult();
+ }
+
+ @Test
+ public void testCheckFindEntity()
+ {
+ Map<String, List<Object>> modelStore = this.stm.getModel();
+ Long carId = new Long(1);
+ LeccyCar car = new LeccyCar(carId);
+ List<Object> carList = new ArrayList<Object>();
+ carList.add(car);
+ carList.add(new LeccyCar(new Long(2)));
+ String carFQCN = "uk.ac.ncl.sdia.a8905943.model.LeccyCar";
+ Assert.assertEquals(carFQCN, car.getClass().getName());
+ modelStore.put(car.getClass().getName(), carList);
+ Assert.assertNotNull(this.entityManager);
+ LeccyCar foundEntity = this.entityManager.find(LeccyCar.class, carId);
+ Assert.assertNotNull(foundEntity);
+ Assert.assertNotNull(foundEntity.getId());
+ Assert.assertEquals(foundEntity.getId(), carId );
+
}
+ @Test
+ public void testCheckSelectedNodesMethodBehaviour()
+ {// the default setLenient is false, does the method explode?
+ JXPathContext context = JXPathContext.newContext(this.stm);
+ List entities = context.selectNodes("model/nothing");
+ Assert.assertNotNull(entities);
+ Assert.assertEquals(0, entities.size());
+ }
+
+ @Test (expected=EntityExistsException.class)
+ public void testCheckPersistThrowsEntityExistsExceptino()
+ {
+ Map<String, List<Object>> modelStore = this.stm.getModel();
+ Long carId = new Long(1);
+ LeccyCar car = new LeccyCar(carId);
+ List<Object> carList = new ArrayList<Object>();
+ carList.add(car);
+ String carFQCN = "uk.ac.ncl.sdia.a8905943.model.LeccyCar";
+ Assert.assertEquals(carFQCN, car.getClass().getName());
+ modelStore.put(car.getClass().getName(), carList);
+
+ LeccyCar duplicate = new LeccyCar(new Long(1));
+ Assert.assertEquals(car.getId(), duplicate.getId());
+
+ this.entityManager.persist(duplicate);
+ }
+
+ @Test
+ public void testCheckQueryDoesNotReturnRemovedEntity()
+ {
+ Map<String, List<Object>> modelStore = this.stm.getModel();
+ Long carId = new Long(1);
+ LeccyCar car = new LeccyCar(carId);
+ List<Object> carList = new ArrayList<Object>();
+ carList.add(car);
+ modelStore.put(car.getClass().getName(), carList);
+
+ this.entityManager.remove(car);
+ Query query = this.entityManager.createQuery("model/"+car.getClass().getName());
+ List resultSet = query.getResultList();
+ Assert.assertNotNull(resultSet);
+ Assert.assertEquals(0, resultSet.size());
+ }
+
@Override
public void setUp() {
super.setUp();
- this.entityManager = new STMEntityManagerImpl(new STMConnection(new STMXAConnectionImpl(new STMXADatasourceImpl(), this.stm)));
+ STMConnection stmConnection = new STMConnection(
+ new STMXAConnectionImpl(new STMXADatasourceImpl(), this.stm));
+
+ this.entityManager = new STMEntityManagerImpl(stmConnection);
}
-
+ @Override
+ public void tearDown() {
+ super.tearDown();
+ this.entityManager = null;
+ }
}
More information about the jboss-svn-commits
mailing list