import java.io.*;
public class ObjectCloner {
// so that nobody can accidentally create an ObjectCloner object
private ObjectCloner() {
}
// returns a deep copy of an object
static public Object deepCopy(Object oldObj) throws Exception {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); // A
oos = new ObjectOutputStream(bos); // B
// serialize and pass the object
oos.writeObject(oldObj); // C
oos.flush(); // D
ByteArrayInputStream bin = new ByteArrayInputStream(bos
.toByteArray()); // E
ois = new ObjectInputStream(bin); // F
// return the new object
return ois.readObject(); // G
} catch (Exception e) {
System.out.println("Exception in ObjectCloner = " + e);
throw (e);
} finally {
oos.close();
ois.close();
}
}
}
Sunday, May 16, 2010
Deep Copy of java object graph
The following method uses serialization to make deep copies and avoid extensive manual editing or extending of classes. Need to make sure that all classes in the object's graph are serializable.
Array Copy with Java 6
@Test
public void genericArrayCopyOf() {
Number[] source = { new Double(5.0), new Double(10.0) };
Number[] target = Arrays.copyOf(source, source.length);
assertEquals(source, target);
}
@Test
public void copyOfWithRange() {
String[] source = { "0", "1", "2", "3", "4" };
String[] target = Arrays.copyOfRange(source, 2, 4);
assertEquals(new String[] { "2", "3" }, target);
}
@Test
public void genericArrayCopyOfWithNewType() {
Number[] source = { new Double(5.0), new Double(10.0) };
Double[] target = Arrays.copyOf(source, source.length, Double[].class);
assertEquals(source, target);
}
Tuesday, May 11, 2010
Parallel class hierarchies with Java Generic
import java.util.ArrayList;
import java.util.Collection;
/*
* Super class for Habitat hierarchy
*/
public abstract class Habitat <A extends Animal> {
/*
* A generic collection that can hold Animal
* or any subclass of animal
*/
Collection<A> collection = new ArrayList<A>();
/*
* add an Inhabitant to the collection.
* should be overridden by subclass
*/
public abstract void addInhabitant( A animal);
}
/*
* Aquarium class inherit the collection from
* Habitat superclass. But limit the collection
* to Fish type.
*/
public class Aquarium extends Habitat <Fish>
{
/*
* (non-Javadoc)
* @see Habitat#addInhabitant(Animal)
*/
@Override
public void addInhabitant( Fish fish) {
collection.add(fish);
System.out.println(Aquarium.class);
}
}
/*
* Super class for Animal hierarchy
*/
public abstract class Animal {
}
public class Fish extends Animal {
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Animal animal = new Fish();
Fish fish = new Fish();
//new Aquarium().addInhabitant(Animal); -- would cause compiler error
new Aquarium().addInhabitant(fish);
}
}
Sunday, May 9, 2010
SQL Windowing
Suppose, we have a "Contract_Transaction" table which keeps a history of transaction of contracts. It actually facilities the General Ledger Entry in the Financial Book. The idea is never to update a transaction, always add a positive or negative $ amount to mimic Debit and Credit. As an example, if a contract-worth $100-is sold, the transaction table would record $100. But if contract is cancelled and $40 is refunded, then record another entry with -$40 for the same contract.
If we like to know the net value of each contract, we just need to do a group by with contract number. But if we like to know the latest status of contract with the net value simple group by won't do it. we need to use the SQL Windowing to achieve that. We not only need sum up each contract but also to rank each row within the contract number by date. Then we only keep the row with latest date or rank 1. Here is an example.
If we like to know the net value of each contract, we just need to do a group by with contract number. But if we like to know the latest status of contract with the net value simple group by won't do it. we need to use the SQL Windowing to achieve that. We not only need sum up each contract but also to rank each row within the contract number by date. Then we only keep the row with latest date or rank 1. Here is an example.
CREATE TABLE "Contract_Transaction" ( "Contract_Number" int2 DEFAULT NULL, "Contract_Status" char(1) DEFAULT NULL, "Contract_Amount" numeric DEFAULT NULL, "Change_Date" date DEFAULT NULL )
insert into Contract_Transaction values (1,'Active',100.00, '2010-4-1');
insert into Contract_Transaction values (1,'Cancel',-40.00, '2010-4-3');
insert into Contract_Transaction values (2,'Active', 50.00, '2010-4-2');
WITH RNK (Contract_Number, Contract_Status, Contract_Amount, RNK) AS
( SELECT Contract_Number,
Contract_Status,
sum(Contract_Amount) OVER ( PARTITION BY Contract_Number ORDER BY Change_Date ROWS UNBOUNDED PRECEDING ),
RANK() OVER (PARTITION BY Contract_Number ORDER BY Change_Date )
FROM Contract_Transaction )
SELECT * FROM TMP WHERE RNK = 1
Thursday, April 29, 2010
Unit testing with EasyMock and Spring
Let's come up with simple test scenario. I have two Spring Service implementations with corresponding interfaces. I like to test only the process method in FooServiceImp class in isolation.
The problem is FooServiceImp.peocess() calls FooBarService.process() method which I don't want to test with this peticular Unit test.
So how do I test just FooServiceImp.process() method without testing FooBarService. EasyMock is to rescue. Before the testing I can replace the reference of FooBarService to a EasyMock object and add certain expected behavior to the Mock.
Behaviors I like to add to mock:
1. The return value of the Mock service.
2. Capture the parameters passed to the Mock
Service.
3. Add a Exception to test Exception scenario
Here are the codes. Happy Unit Testing:
FooServiceTest.java
FooService.java
FooServiceImp.java
FooBarService.java
FooBarServiceImp.java:
Foo.xml - Spring conf file
The problem is FooServiceImp.peocess() calls FooBarService.process() method which I don't want to test with this peticular Unit test.
So how do I test just FooServiceImp.process() method without testing FooBarService. EasyMock is to rescue. Before the testing I can replace the reference of FooBarService to a EasyMock object and add certain expected behavior to the Mock.
Behaviors I like to add to mock:
1. The return value of the Mock service.
2. Capture the parameters passed to the Mock
Service.
3. Add a Exception to test Exception scenario
Here are the codes. Happy Unit Testing:
FooServiceTest.java
import static org.junit.Assert.*;
import java.util.List;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration(locations = { "classpath:Foo.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class FooServiceTest
{
//Get a reference of FooServiceImp from Spring contexts
@Autowired
FooServiceImp fooService;
@Before
public void setUp()
throws Exception
{
//Replace with EasyMock object
fooService.fooBarService = EasyMock.createNiceMock(FooBarService.class);
}
/*
* Test the regular scenario
*/
@Test
public void testFooService() throws Exception{
//Creating a input value of String array
String[] values = {"value1","value2", "value3"};
//Create Easymock Capture type to capture the
Capture<List<String>> captureValues = new Capture<List<String>>();
//Setting behavior for the Mock service.
EasyMock.expect(fooService.fooBarService.process( EasyMock.capture(captureValues))).andReturn("value1");
EasyMock.replay(fooService.fooBarService);
//Test the return value
assertEquals(fooService.process(values),"value1");
EasyMock.verify(fooService.fooBarService);
//Check the parameters on Mock service call
assertEquals(captureValues.getValue().get(0),"value1");
}
/*
* Test the Exception scenario
*/
@Test(expected = Exception.class)
public void testFooServiceException() throws Exception{
EasyMock.reset(fooService.fooBarService);
String[] values = {"value1","value2", "value3"};
Capture<List<String>> captureValues = new Capture<List<String>>();
//Setting the expected Exception on the Mock service
EasyMock.expect(fooService.fooBarService.process( EasyMock.capture(captureValues))).andThrow(new Exception());
EasyMock.replay(fooService.fooBarService);
//Should get an exception to pass the test
fooService.process(values);
}
}
FooService.java
public interface FooService
{
public String process(String[] values) throws Exception;
}
FooServiceImp.java
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
public class FooServiceImp
implements FooService
{
@Autowired
FooBarService fooBarService;
@Override
public String process(String[] values) throws Exception
{
List<string> arrayList = Arrays.asList(values);
System.out.println(arrayList);
return fooBarService.process((List<string>)Arrays.asList(values));
}
}
FooBarService.java
import java.util.List;
public interface FooBarService
{
public String process(List<String> values) throws Exception;
}
FooBarServiceImp.java:
import java.util.List;
public class FooBarServiceImp
implements FooBarService
{
@Override
public String process(List<String> values) throws Exception
{
System.out.println("In FooBar" + values.get(0));
return values.get(0);
}
}
Foo.xml - Spring conf file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:amq="http://activemq.apache.org/schema/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <bean id="fooService" primary="true" class="com.icrossing.service.FooServiceImp"> </bean> <bean id="fooBarService" primary="true" class="com.icrossing.service.FooBarServiceImp"> </bean> </beans>
Tuesday, April 27, 2010
HibernateJMX with Spring
Hibernate Mbean is nice way to get runtime Hibernate Stat. Here is how to publish Hibernet Mbean to Tomcat Mbean server with Spring. Once Mbean are published, it can be access through Jconsole.
Tomcat setup:
Spring config:
Hibernate property:
Tomcat setup:
JAVA_OPTS=" -Dcom.sun.management.jmxremote.port=9002 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.awt.headless=true"
Spring config:
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="Hibernate:name=statistics">
<ref local="statisticsBean">
</ref>
</entry></map>
</property>
</bean>
<bean id="statisticsBean" class="org.hibernate.jmx.StatisticsService">
<property name="statisticsEnabled">
<value>true</value>
</property>
<!-- Change this to match you own system if needed -->
<property name="sessionFactory"><ref local="sessionFactory"></ref>
</property>
</bean>
Hibernate property:
<prop key="hibernate.generate_statistics">true</prop>
Tuesday, April 20, 2010
Pivot Table with SQL
One on my favourite technique with SQL is creating
pivot table. Here is an easy example using Postgres:
Pivoting SQL:
-------------------------------------------
YR | Q1 | Q2 | Q3 | Q4
-------------------------------------------
2000 | 240 | 200  | 230 | 120
2001 | 320 | 340 | 290 | 100
pivot table. Here is an easy example using Postgres:
CREATE TABLE REVENUE
( YR int4,
QT chat,
REVENUE numeric);
insert into REVENUE values (2000, 'Q1', 240);
insert into REVENUE values (2000, 'Q2', 200);
insert into REVENUE values (2000, 'Q3', 230);
insert into REVENUE values (2000, 'Q4', 120);
insert into REVENUE values (2001, 'Q1', 320);
insert into REVENUE values (2001, 'Q2', 340);
insert into REVENUE values (2001, 'Q3', 290);
insert into REVENUE values (2001, 'Q4', 100);
Pivoting SQL:
SELECTThe result set going be pivoted
YR,
MAX(CASE WHEN QT = 'Q1' THEN REVENUE END) Q1,
MAX(CASE WHEN QT = 'Q2' THEN REVENUE END) Q2,
MAX(CASE WHEN QT = 'Q3' THEN REVENUE END) Q3,
MAX(CASE WHEN QT = 'Q4' THEN REVENUE END) Q4
FROM
REVENUE
GROUP BY YR
-------------------------------------------
YR | Q1 | Q2 | Q3 | Q4
-------------------------------------------
2000 | 240 | 200  | 230 | 120
2001 | 320 | 340 | 290 | 100
Monday, April 19, 2010
Hibernate CacheMode.IGNORE option
Recently, I have ran into a hibernate related issue in our production system. We have a nightly batch program that reads a lot of rows from one table, then does some conversion and writes to a file. It brings 5000 rows in chunk, still we saw the nightly program took the server down with outOfMemory error when processing large number of rows.
After some investigation, I have found that the program brings out all the data in one session. Hibernate is holding all the objects in its session until session is closed. As a result, the GC can't clear any previous chunk of object from memory.
Since the we are reading the data for readonly purpose, we set the CacheMode.IGNORE on the Query object. It prevents Hibernate to hold the reference of the objects in it's session.
Here is snippet of the code.
After some investigation, I have found that the program brings out all the data in one session. Hibernate is holding all the objects in its session until session is closed. As a result, the GC can't clear any previous chunk of object from memory.
Since the we are reading the data for readonly purpose, we set the CacheMode.IGNORE on the Query object. It prevents Hibernate to hold the reference of the objects in it's session.
Here is snippet of the code.
Query qry = session.createQuery(query).setCacheMode(CacheMode.IGNORE);
Subscribe to:
Posts (Atom)