Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, 26 July 2010

Spring -Junit - Testing

Create unit tests the Spring way.

This requires version 4.4 of junit (for v2.5.6 of Spring)
Add the SpringTest module to the test libs

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/MyTestConfig.xml")
public class MyClassTest extends AbstractTransactionalJUnit4SpringContextTests // For Tx enabled tests

Can annotate methods with @NotTransactional to not have a TX created for a method in the test. Methods called inside will still
create TX if they require one.

Don't forget to create your own EntityManager of SessionManager for your persistance.


<context:annotation-config />
<context:component-scan base-package="com.stuff"/>
<aop:aspectj-autoproxy/>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>


<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:persistence-test.xml"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="SQL_SERVER" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url" value="jdbc:sqlserver://127.0.0.1:1433;databaseName=My-TEST" />
<property name="username" value="UserName" />
<property name="password" value="Password" />
</bean>

Wednesday, 16 June 2010

Spring - JUnit - Mocking JNDI

JNDI You are awful..

Oh ok, not that kind of mocking. But seriously if you are doing this in a spring bean:

@Resource
private String rootURL

Then you can use Spring to define a a bean to fill it in, then all is well. But what if you are doing:

@Resource(mappedName="rootURL")
private String rootURL

Well then you are most likely using something like a deployment descriptor (e.g. web.xml) to define the environment variable e.g.

    <env-entry>
        <description>Root URL for a blog</description>
        <env-entry-name>rootURL</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>http://www.blogger.com</env-entry-value>
    </env-entry>


But what happens when you try to use JUnit, probably nothing bad, but what if you are using Spring to run your JUnit? Then you will most likely get this kind of error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'blogDAO':
Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'rootURL' defined in JNDI environment:
JNDI lookup failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

This is down there not being the JNDI eniroment you were expecting, so how can you mock one up? Buy adding this to your JUnit test:

public static void buildJndi() {

        try {

            SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();

            String rootURL = "http://www.blogger.com";
            builder.bind("rootURL", rootURL);

        } catch (NamingException e) {

        }

    }

and calling it in the unit tests constructor.

For more information checkout:
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/mock/jndi/SimpleNamingContextBuilder.html

Tuesday, 8 June 2010

Accessing Spring Beans in Servlet

Sometimes you just have to do the do in a servlet. Here is a nice cheeky little way of getting to the applciation context:

WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext())

Then from there you can use getBean() etc...

Ref: http://forum.springsource.org/showthread.php?t=18833

Tuesday, 6 April 2010

Quartz 1.6.1 and Spring FW 2.5.6 Jobs Stopping

So for a while I've been trying to track down why my jobs running on a org.springframework.scheduling.quartz.SchedulerFactoryBean seemingly stop quite arbitrarily and in groups of Triggers contained within each SchedulerFactoryBean. No exceptions are being thrown from application code and there is no advice setup on the application classes. Application code completes before the job not running correctly again.

I recently decided to try upgrading Quartz as the library I was using was rather old. Quartz 1.7.3 was installed and this problem has not been experienced since. Sorry for the lack of great insight into the cause here, but hopefully my experiences will help put the minds to rest of those being driven similarly insane by this problem.

Monday, 8 March 2010

PersistenceUnit - PersistenceContext

But what does it all mean???

I don't know if it is because at this point in time I am suffering from a cold and a pair of ulcers are having a party in my mouth. But I am struggling to come to terms with the difference between and PU and PC...

After a quick Google on @PersistenceUnit vc @PersistenceContext I have deduced the following:
A PU will give you an EntityManagerFactory
A PC will give you an EntityManager

Now when to use either, really comes down to your TX strategy, who is managing your connections etcetc.
Using Spring I have always used PC to inject in a Spring managed EM to do the do with. However why is this?
  • @PersistenceUnit annotation is used in J5SE applications to handle Java Persistence API (JPA) persistence management. You may use a PeristenceUnit in an application inside a container, but it must be managed by the developer instead of the container.
  • @PersistenceContext annotation is used for Container Managed Persistence (CMP). This relieves the developer of having to worry about connection management.
and I think this link describes this nicely:

http://java.dzone.com/tips/how-use-glassfish-managed-jpa

Saturday, 9 January 2010

Spring - PostConstruct

Found that using @PostConstruct doesn't have transactional ability. Looking around I found this link:

http://forum.springsource.org/showthread.php?t=81832

So by implementing the app listener you can have it bootstrap the configuration once the context has finished loading.

@Repository
public class MyDAOImpl implements ApplicationListener, MyDAO {

    @Transactional(propagation=Propagation.REQUIRED)
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            postCreate();
        }

    }

    public void postCreate() {
      //Code
      
        }
    }

Friday, 8 January 2010

JPA + The Cat + Spring

App context:

<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="false" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    </properties>
  </persistence-unit>
</persistence>

JPA + The Fish + Spring

In the app context
<context:annotation-config />
<tx:jta-transaction-manager />
<tx:annotation-driven transaction-manager="transactionManager" />
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPU"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

In the web.xml

<persistence-unit-ref>
<persistence-unit-ref-name>persistence/myPU</persistence-unit-ref-name>
<persistence-unit-name>myPU</persistence-unit-name>
</persistence-unit-ref>

In the persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myDatasource</jta-data-source>
<properties>
<property name="hibernate.bytecode.provider" value="cglib"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>

Then to access in code:

@PersistenceContext
private EntityManager entityManager;

Thursday, 7 January 2010

Remote EJB access in Spring

<jee:jndi-lookup id="mySpringId" jndi-name="ejb/garBean">
<jee:environment>
//This tells spring to look here for the bean, if these aren't specified default to the localhost and 3700
org.omg.CORBA.ORBInitialHost=192.168.1.20
org.omg.CORBA.ORBInitialPort=3700

</jee:environment>
</jee:jndi-lookup>

 @Stateless(name="garBean", mappedName="ejb/garBean")
@Remote(GarBeanRemote.class)
public class GarBean implements GarBeanRemote

java.lang.NoSuchMethodError - Spring - SpringBeanAutowiringSupport

SEVERE: WSSERVLET11: failed to parse runtime descriptor: java.lang.NoSuchMethodError: org.springframework.web.context.ContextLoader.getC urrentWebApplicationContext()Lorg/springframework/web/context/WebApplicationContext;

Was thrown when using auto-wiring a service to a web-service class.

Fixed by moving to 2.5.6