Spring Roo @RooEntity from 1.1.x replaced in 1.2.x

If you have an older Spring Roo project created from Spring Roo 1.1.x and you’re trying to imported it to a more recent STS version and/or trying to upgrade to a later 1.2.x version of Spring Roo, you may be seeing these errors:

RooEntity cannot be resolved to a type

@RooEntity was replaced in Spring Roo 1.2.x with @RooJpaActiveRecord. Replace this in all your Entity classes and you should be good to go.

This is discussed in this thread.

@RooJpaActiveRecord is covered in the docs here.

Using Spring 3.1 Profiles

Profiles in Spring 3.1+ give you the ability to define conditional bean configurations based on a profile name, where one of your defined profiles is selected at runtime based on a selected profile name.

For example, if you have certain beans that are needed for running in a certain deployment environment but not needed for others (dev, test or prod), or if certain beans need to be configured differently between different environments, Profiles give you the ability to do exactly this.

If you’re using XML configuration, you use the profile=”…” attribute on the
<beans> element. For example:

<beans>
    <beans profile="dev">
        ... bean defs for dev profile here
    </beans>

    <beans profile="prod">
        ... bean defs for prod profile here
    </beans>
</beans>

To select your profile at runtime you’ve got a couple of different options – the easiest approach is to declare a system property, or -D parameter to your JVM at startup:

-Dspring.profiles.active=dev

When you initialize your Application Context, Spring automatically checks for this property and then will initialize only the beans declared for that specific profile. Beans not within a profile will still get initialized, or alternatively a profile with the name ‘default’ will get initialized if no other profile is specified.

Another approach if you need more control over the logic to determine which profile is active on startup, you can programmatically select your profile like this:

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();

if( ... some logic here)
{
    ctx.getEnvironment().setActiveProfiles("example_profile_1");
}
else
{
    ctx.getEnvironment().setActiveProfiles("example_profile_2");
}

ctx.load("classpath:applicationContext.xml");
ctx.refresh();

Notice with this approach, since we’re not using the spring.profiles.active property, we don’t want to load the context xml file until after we’re determined programmatically which profile is active (based on some logic), then we set the profile with setActiveProfiles(), then load the xml, and refresh the context to initialize our beans for the selected profile.

Core Spring – continued (2) – SpEL, Annotation based bean defs, Java-based configuration

Spring Expression Language (SpEL) introduced in Spring 3.0 introduces EL style language for referencing beans and properties, and gives a standard syntax for doing property replacement into beans.

Annotation based bean definition

  • component scan allows you to configure annotated beans – simplest approach, avoids xml:

Enabled with context:component-scan in xml file:

<context:component-scan base-package="your.package"/>
  • @Component – declares beans
  • @Autowired – bean of a matching type is automatically injected into contructor, method, or field
  • Only one constructor can be autowired, but multiple methods and attributes can be autowired
  • @Autowired properties don’t need setters
  • @Autowired methods don’t need to be setters, and don’t need to be named ‘set…()’
  • @Qualifier allows you to specify a specific bean id if matching beans by type is ambiguous

‘The spirit of autowiring is by type’ – use of the @Qualifier should be only if necessary, since it restricts the flexibility and power of the Autowiring.

Use of @Autowired implies @Required (don’t need to explicitly defined @Required if @Autowired)

Stereotype annotations

Also enabled via context:component-scan

  • @Service – indicates purpose in layering, but doesn’t add any additional behavior

Following stereotypes do add extra behavior:

  • @Repository – data access
  • @Controller – MVC controller
  • @Configuration – programmatic Spring configuration

Other Spring projects use similar annotation approach for adding additional stereotype based functionality.

JSR 330 CDI Annotation Support

  • Spring is a an implementation of JSR330
  • provides support for JSR330 standard @Named, @Inject, @Scope, @Singleton
  • Spring provides other Spring specific annotations not supported in JSR330 (@Value, @Required, @Lazy)

Bean configuration using Annotations & Java: @Configuration

  • Enabled with context:component-scan
  • @Configuration marks configuration clas
  • Use @Bean on method that provides instance of the bean
  • Method name is the id of the bean, eg participantService() – id = “participantService”
  • Java code can perform any initialization – you can invoke any other methods necessary to perform initialization
  • All @Bean annotated methods produce singletons by default – @Bean methods are proxied to add this behavior – this can be overridden with @Scope(“prototype”)
  • @Import allows to import other @Configuration classes
  • Alternate configuration: AnnotationConfigApplicationContext – instantiating this context allows a completely xml free configuration approach

 

Annotations vs XML based configuration

  • easier to make changes to annotated beans during development
  • could always move to xml config when beans become more mature, but no compelling reason to do this, could always just leave the annotations
  • xml config always overrides the annotation metadata

Spring JUnit Support
Integration testing support allows testing with Spring Bean dependencies

@ContextConfuguration("example-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class ExampleTest
{
    @Autowired
    private ExampleService exampleService;

    @Test
    public void eampleTest() { ... }
}

Using Spring with JPA and Hibernate

Spring + Hibernate

  • HibernateTemplate is now obsolete (Spring 3.x +) – create bean for SessionFactory and wire it into Hibernate-based Repository beans
  • Use the Hibernate Session api directly
  • This approach has zero dependency on Spring APIs

How to configure:

Configure beans for your datasource, transaction manager and the SessionFactory:

<jee:jndi-lookup id="myDataSource" jndi-name="java:comp/env/jdbc/myds"/>

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="jtaTransactionManager" ref="txManager"/> 
    <property name="mappingResources">
      <list>
        <value>product.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.HSQLDialect
      </value>
    </property>
  </bean>

Configuring with xml files is optional if you’re using JPA annotations for your Entities instead.

Repositories using Hibernate follow same ‘new’ pattern as JDBC Template with Spring 3.x, no longer user the HibernateTemplate, inject a Hibernate SessionFactory and use this to get a Session directly. This approach doesn’t have any Spring code dependencies:

@Transactional
@Repository
public class ExampleRespositoryImpl implements ExampleRepository
{
  private SessionFactory sessionFactory;

  public ExampleRespositoryImpl(SessionFactory sessionFactory)
  {
    this.sessionFactory(sessionFactory);
  }

  public Example findExampleById(Long id)
  {
    this.sessionFactory.getCurrentSession().get(Example.class, id);
  }
}

Spring + JPA

How to configure:

Running in an EE container, configure your datasource, transaction manager and EntityManagerFactoryBean:

<jee:jndi-lookup id="dataSource" jndi-name="java:jboss/datasources/MysqlDS"/>

<bean id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/persistenceUnit"/>

If you’re running outside of an EE container, instead of looking up your datasource and container provided EntityManagerFactory, define a LocalEntityMangerFactoryBean, referencing your persistence unit name:

<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="dataSource" ref="dataSource"/>
 </bean>

Configure your persistence.xml to reference your datasource and JPA provider (which may also be Hibernate):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="JTA"><!-- for local testing use: RESOURCE_LOCAL -->
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
         <!-- KH: look up DataSource from container -->
         <jta-data-source>java:jboss/datasources/MysqlDS</jta-data-source>

        <properties>
            <!-- KH: ask JBoss to publish the EntityManager so we can reference it in the Spring config -->
            <property name="jboss.entity.manager.factory.jndi.name" value="persistence/persistenceUnit"/>

            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
            <property name="hibernate.connection.charSet" value="UTF-8"/>

        </properties>
    </persistence-unit>
</persistence>

If you’re running outside of an EE container, make the following changes:

  • transaction-type="RESOURCE_LOCAL"
  • remove the <jta-data-source> element

Write Repositories with @Repository and @Transactional, and use the @PuersistenceUnit annotation to inject the EntityManagerFactory

@Transactional
@Repository
public class ExampleRespositoryImpl implements ExampleRepository
{
  private EntityManagerFactory emf;

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public Collection loadProductsByCategory(String category) {
        EntityManager em = this.emf.createEntityManager();
        try {
             Query query = em.createQuery("from Product as p where p.category = ?1");
             query.setParameter(1, category);
             return query.getResultList();
        }
        finally {
            if (em != null) {
                em.close();
            }
        }
    }
}

This approach injects the EntityManagerFactory using @PersistenceUnit, from which you can get hold of the EntityManager. The normal approach with JPA would be to inject the EntityManager with @PersistenceContext and use the EntityManager directly.