I really never have used memory databases. I have never had a requirement to use one and I always have Oracle, PostgreSQL, SQL Server or MySQL laying around to use. I looked around and took a poll from the user's group and it came down to Derby or HSQLDB. Derby is not officially supported by Hibernate and I had some issues getting it to work so I chose to go with HSQLDB.
Enough talk...now we look at the integration into Spring. Remember I already have one datasource, so I had to add a second one in the applicationContext.xml.
<bean id="inMemDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- <property name="driverClassName"><value>org.apache.derby.jdbc.EmbeddedDriver</value></property>
<property name="url"><value>jdbc:derby:InMemoryDatabase;create=true</value></property> -->
<property name="driverClassName"><value>org.hsqldb.jdbcDriver</value></property>
<property name="url"><value>jdbc:hsqldb:mem:SessionInfo</value></property>
<property name="username"><value>sa</value></property>
<property name="password"><value></value></property>
</bean>
<bean id="inMemorySessionFactory"
class="com.application.spring.AutomatedAnnotationSessionFactoryBean">
<property name="dataSource" ref="inMemDataSource" />
<property name="automaticAnnotatedPackages">
<list>
<value>com.application.domain.memory</value>
</list>
</property>
<property name="annotatedPackages">
<list>
<value>com.application.domain.memory</value>
</list>
</property>
<!-- annotated source files -->
<!-- <property name="annotatedClasses">
<list>
<value>example.Account</value>
<value>example.AccountDetail</value>
<value>example.Employee</value>
</list>
</property> -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.generate_statistics">true</prop>
<!-- <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop> -->
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.validator.apply_to_ddl">true</prop>
<!-- <prop key="hibernate.validator.autoregister_listeners">true</prop>
<prop key="hibernate.validator.apply_to_ddl">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop> -->
<!-- <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</prop> -->
</props>
</property>
<property name="entityInterceptor">
<ref bean="modificationInterceptor"/>
</property>
</bean>
<!-- Hibernate Template definition -->
<bean id="inMemoryHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<constructor-arg ref="inMemorySessionFactory"/>
<constructor-arg type="boolean" value="false"/>
</bean>
Now I created a simple domain object to map.
@Entity
@Hibernate
@Table(name="SIMPLE_OBJECT")
public class SimpleObject extends DataObject implements java.io.Serializable{
private Integer id;
private String name;
@Override
@Id
@Column(name="SESSION_ID")
public Integer getId() {
return id;
}
@Override
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now comes the part where I was a little foggy on. I needed to create a new DAO that utilized the new datasource using Spring annotations. Keep in mind that using @Autowire is great until two beans of the same type are defined in the same context. In that case, to select a particular one, you need to @Qualifier annotation.
@Repository("simpleObjectDAO")
public class SimpleObjectDAO extends GenericDAO{
protected SimpleObjectDAO() {
super(SessionInfo.class);
}
@Autowired// setHibernateTemplate is final in superclass so we cannot autowire it by default
@Override
public void setMyHibernateTemplate(@Qualifier("inMemoryHibernateTemplate") final HibernateTemplate template) {
setHibernateTemplate(template);
}
}
now, let's write a JUnit test to insure our new setup works.
public class SimpleObjectDAOTest {
@SpringBeanByType
SimpleObjectDAO simpleObjectDAO;
@Test
public void createRandomSimpleData() {
for (int i =0; i < 100; i++) {
SimpleObject session = new SimpleObject ();
session.setId(i);
session.setName("Name: " + i);
simpleObjectDAO.save(session);
}
}
@Test
public void findAllInformation() {
Collection sessions = simpleInfoDAO.getAll();
log.debug("Session: " + sessions.size());
for (SimpleObject session : sessions) {
log.debug("ID: " + session.getId());
log.debug("Name: " + session.getBanknr());
}
}
There you have it, a quick in memory database. It is super fast as well it should be since it is all in memory. HSQLDB rocks. I think I will have plenty of more uses for this technique later on. Keep in mind that since my primary database is Oracle I could have done the same thing using a temporary table in Oracle and map my hibernate object to it. I like the HSQLDB approach better though, since it eliminates another database vendor dependency that I do not need hanging around my project. Another plus is that I can switch out my memory databases with a simple flick of the configuration. Man, do I love working with Spring and Hibernate. I think I mention this a lot.

3 comments:
I liked H2 Database more than HSQLDB, It's actually faster
I second that! H2 it has many more features and it's much faster.
Third it.
Post a Comment