Here are the results i got after trying out all spring abstract
support
classes for JUnit :
Spring Test Superclass
Test result
Problem
org.springframework.test.AbstractDependencyInjectionSpringContextTests
Pass
org.springframework.test.AbstractTransactionalSpringContextTests
Pass
org.springframework.test.AbstractSingleSpringContextTests
Pass
org
.springframework
.test.AbstractTransactionalDataSourceSpringContextTests
Pass
org
.springframework
.test.annotation.AbstractAnnotationAwareTransactionalTests
Pass
org.springframework.test.jpa.AbstractJpaTests
Fail
ClassNotFoundException - Apparently a problem with the class loader
OrmXmlOverridingShadowingClassLoader
Here's my sample test case:
public class UserEaoTest extends
AbstractTransactionalSpringContextTests {
private GenericEao userEao;
protected String[] getConfigLocations() {
setAutowireMode(AUTOWIRE_BY_NAME);
return new String[] {
"classpath*:/applicationContext-eao.xml"
};
}
public void testCRUD() throws Exception{
User user = new User();
user.setName("John");
user.setLastName("Doe");
user.setStatus(new Short("1"));
//Test create
user = userEao.save(user);
assertNotNull("Create failed...", user.getUserId());
Long userId = user.getUserId();
user = null;
//Test read
try {
user = userEao.get(userId);
} catch (RuntimeException e) {
fail("Read failed...");
}
assertNotNull(user);
//Test update
user.setStatus(new Short("2"));
userEao.save(user);
assertEquals("Update failed...",
userEao.get(userId).getStatus(),new
Short("2"));
//Test delete
user = null;
userEao.remove(userId);
try {
user = userEao.get(userId);
} catch (RuntimeException e) {
assertNull(user);
}
}
//Injected by Spring
public void setUserEao(GenericEao userEao) {
this.userEao = userEao;
}
}
The test case unit-tests a simple EAO that is managed by spring.
Notice that
depending on the spring abstract superclass, the test case may require
subtle changes.
The spring application context file has the following definitions:
<!-- Initializes openEjb context-->
<bean id="openEjbContext"
class="net.quarksoft.arquetipo.eao.support.OpenEjbFactoryBean">
<property name="jndiEnvironment">
<props>
<prop
key="myDs">new://Resource?type=DataSource</prop>
<prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</
prop>
<prop key="myDs.JdbcUrl">
jdbc:mysql://localhost/midastest?
createDatabaseIfNotExist
=true&useUnicode=true&characterEncoding=utf-8
</prop>
<prop
key="myDs.UserName">root</prop>
<prop key="myDs.Password"></prop>
</props>
</property>
</bean>
<!-- Obtains EntityManagerFactory from OpenEjb context via a
custom bean
factory -->
<bean id="entityManagerFactory"
class
="net.quarksoft.arquetipo.eao.support.EntityManagerFactoryBean">
<property name="context" ref="openEjbContext" />
</bean>
<!-- Obtains TransactionManager from OpenEjb context via a
custom bean
factory-->
<bean id="transactionManagerFactory"
class
=
"net
.quarksoft.arquetipo.eao.support.TransactionManagerFactory"></
bean>
<!-- Wraps OpenEjb's TransactionManager with spring's
JtaTransactionManager so that it can be injected to spring's abstract
transactional tests -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager"
ref="transactionManagerFactory"></property>
</bean>
<!-- bean post-processor for JPA annotations -->
<bean
class
=
"org
.springframework
.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"
/>
<!-- My persistent bean definition -->
<bean id="userEao"
class="net.quarksoft.arquetipo.eao.jpa.GenericEaoJpa">
<constructor-arg value="net.quarksoft.arquetipo.model.User" /
>
</bean>
These are the custom bean factories used to obtain the required
resources
from OpenEjb context:
/**
* Custom spring factory to initialize OpenEjb context
*
*/
public class OpenEjbFactoryBean implements FactoryBean {
private Properties properties = new Properties();
public OpenEjbFactoryBean() {
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
}
public Properties getJndiEnvironment() {
return properties;
}
public void setJndiEnvironment(Properties properties) {
this.properties.putAll(properties);
}
public Object getObject() {
try {
return new InitialContext(properties);
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
public Class getObjectType(){
return Context.class;
}
public boolean isSingleton() {
return true;
}
}
/**
* Obtains an instance of EntityManagerFactory from the openEjb context
*/
public class EntityManagerFactoryBean implements FactoryBean {
private Context context;
public Object getObject() {
try {
ResourceLocal bean = (ResourceLocal) context
.lookup("ResourceBeanLocal");
return bean.getEntityManagerFactory();
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
public Class getObjectType() {
return EntityManagerFactory.class;
}
public boolean isSingleton() {
return true;
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
}
/**
* Obtains an instance of javax.transaction.TransactionManager from
* the OpenEjb context
*/
public class TransactionManagerFactory implements FactoryBean {
public Object getObject() throws Exception {
return org.apache.openejb.OpenEJB.getTransactionManager();
}
public Class getObjectType() {
return TransactionManager.class;
}
public boolean isSingleton() {
return true;
}
}
The persistence.xml definition:
<persistence-unit name="ApplicationEntityManager"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</
provider>
<jta-data-source>myDs</jta-data-source>
<class>myapp.model.User</class>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect" />
<property
name="hibernate.transaction.manager_lookup_class"
value="org.apache.openejb.hibernate.TransactionManagerLookup"/>
</properties>
</persistence-unit>
Finally, the persistent Entity and the generic implementation of the
EAO:
@Entity
@Table(name = "user")
public class User implements Serializable{
private static final long serialVersionUID = -8787893234778745429L;
private Long userId;
private String name;
private String lastName;
private Short status;
@Column(name = "lastName", length = 30)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name = "name", length = 30)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "status")
public Short getStatus() {
return status;
}
public void setStatus(Short status) {
this.status = status;
}
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
@Column(name = "userId")
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
}
public class GenericEaoJpa implements GenericEao {
protected final Log log = LogFactory.getLog(getClass());
private Class persistentClass;
//Injected by spring postprocessor
@PersistenceContext
private EntityManager entityManager;
public GenericEaoJpa(Class persistentClass) {
super();
this.persistentClass = persistentClass;
}
public boolean exists(Serializable id) {
E entity = entityManager.find(persistentClass, id);
return entity == null? false:true;
}
public E get(PK id) {
E entity = entityManager.find(persistentClass, id);
if (entity == null) {
log.warn("Uh oh, '" + this.persistentClass + "' object
with id
'" + id + "' not found...");
throw new
ObjectRetrievalFailureException(this.persistentClass,
id);
}
return entity;
}
public List getAll() {
return entityManager.createQuery("select " +
persistentClass.getName()).getResultList();
}
public void remove(PK id) {
E entity = get(id);
entityManager.remove(entity);
}
public E save(E entity) {
entityManager.persist(entity);
return entity;
}
}
Hope this helps.
-Jon
--
View this message in context:
http://www.nabble.com/Help-with-OpenEJB3-and-Spring-IoC-tp17674222p17875549.html
Sent from the OpenEJB User mailing list archive at Nabble.com.