Archive for November, 2009

Sharing Resources between Maven modules

Saturday, November 28th, 2009

I needed to share resources between modules in a multi-module Maven project. The resources in question are configuration data files which are converted into objects via XStream (plus some Spring Bean configuration files).  The reason they need to be shared is for instantiation within module-specific JUnit tests.

After some thinking and Googling around, I think I have come up with the ‘cleanest’ structure. My first thought was to put them into the parent module, but after messing around with configuration, I began to realise this was a bad idea.

My new solutions goes like this:

  • Create a new sub-module (called config or whatever)
  • Put a dependency to this new module in the pom.xml for all other modules
  • Even though these are test resources, put them in /src/main/resources so they are packaged into the jar (or obviously change the default packaging so it includes the /src/test/resources)

Quite clean I think.

Injecting Resources into Spring Beans

Saturday, November 28th, 2009

This is mentioned in passing in the Spring documentation – but to highlight:

Spring will automatically convert a String in a bean definition into a Resource if required.

If the target Resource is a specific class (e.g. UrlResource) then the passed in string must match the format, or a runtime error will ensue.

For example:

<bean id="settlement" class="SettlementImpl">
  <constructor-arg index="0" value="/config/transaction/settlement.xml" />
</bean>
public SettlementImpl(Resource settlementResource) {
   SettlementConfig settlementConfig;
   XStream stream = new XStream();
   stream.processAnnotations(SettlementConfig.class);
   try {
     settlementConfig = (SettlementConfig) stream.fromXML(settlementResource.getInputStream());
   } catch (IOException e) {
     // Whatever
   }
    // Rest of class
}

Persisting a Collection with an arbitrary enum type

Friday, November 27th, 2009

As we know, enums are great for storing (relatively) static domain information.

But let’s say we want an object which models (and can persist) a collection of elements where we are not sure at design time which domain information will be stored. For example, a set of attributes describing a financial trade – TransactionSource, BusinessFlow, TradingStrategy, etc. While we could model these all separately, it would be nice to have a single collection of attributes.

In this scenario, we could create a collection (and associated methods) which manipulate Object, but in today’s typesafe world there has to be something better.

I propose creating an empty interface, then having all enums implement it:

public enum TransactionSource implements TransactionAttributeInterface {
	TRADING_SYSTEM, SETTLEMENT_FACTORY;
}

Then, the consuming code becomes simple:

public interface TransactionAttribute {
	void setTransactionAttributeValue(TransactionAttributeInterface transactionAttributeValue);
	TransactionAttributeInterface getTransactionAttributeValue();
}

private Map<TransactionAttributeType, TransactionAttribute> transactionAttributeMap;
TransactionAttribute transactionAttribute = new TransactionAttributeImpl();
transactionAttribute.setTransactionAttributeValue(TransactionSource.TRADING_SYSTEM);

Note that Hibernate will confused when trying to persist TransactionAttribute (as it won’t be able to determine the type of TransactionAttributeInterface). This could be solved by creating a new Hibernate UserType (see https://www.hibernate.org/272.html), or more easily by mapping to a String internally for persistence:

	@Column(name = "tran_attribute_value")
	private String transactionAttributeValue;

	@Override
	public TransactionAttributeInterface getTransactionAttributeValue() {
		return (TransactionAttributeInterface) Enum.valueOf((Class<? extends Enum>)transactionAttributeType.getTransactionAttributeTypeClass(), transactionAttributeValue);
	}

	@Override
	public void setTransactionAttributeValue(TransactionAttributeInterface transactionAttributeValue) {
		this.transactionAttributeValue = transactionAttributeValue.toString();
	}

Fun With Hibernate Inheritance

Wednesday, November 25th, 2009

I had a relatively simple requirement, with a relatively simple solution – but it is worth recording for simple reference.

Suppose I have two Hibernate classes Cat and Dog, both of which derive from the abstract class Animal.  Suppose further that both Cats and Dogs can have a child collection of the class Toy.

Since Set<Toy> is shared, we want to do all the hard work in the Animal class, rather than repeat it twice.

Finally, assume that for convenience sake – the underlying table structure is shared, with just a column to indicate whether the entry is a CAT or a DOG.

public class Cat extends Animal {
  // Implementation
}

public class Dog extends Animal {
  // Implementation
}

public abstract class Animal {
  private Set<Toy> toySet;
  // Implementation
}

public class Toy {
  // Implementation
}
CREATE TABLE animal (
id          BIGINT NOT NULL,
animal_type VARCHAR(10) NOT NULL,
name        VARCHAR(30) NOT NULL,
PRIMARY KEY(id)
)

CREATE TABLE toy (
  id             BIGINT NOT NULL,
  toy_short_desc VARCHAR(50),
  PRIMARY KEY(id)
)

All very simple so far.

If we want to annotate this class to fulfill the requirements above, we have to:

  • Declare Cat and Dog as @Entity, since these become the instantiated classes.
  • ImportantAnimal also needs to be an @Entity to allow for the @ManyToOne mapping in Toy.  (Remember – we said we wanted the ToySet to be shared.  If you don’t declare Animal as an @Entity we will get ‘unknown entity’ exceptions.
  • State that Animal is the top of tree with @Inheritance.
  • Tell Hibernate which column should be used to discriminate between classes when mapping with @DiscriminatorColumn.

So our classes become:

@Entity
@DiscriminatorValue(value = "CAT")
public class Cat extends Animal {
  // Implementation
}

@Entity
@DiscriminatorValue(value = "DOG")
public class Dog extends Animal {
  // Implementation
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "animal_type")
@Table(name = "animal")
public abstract class Animal {
  private Set<Toy> toySet;
  // Implementation
}

public class Toy {
  // Implementation including:
  // @ManyToOne(targetEntity = Animal.class)
}

Hello world!

Sunday, November 22nd, 2009

This blog will contain what I learn from my voyages through development.