Please ! Stop using floating point numbers for financial data

Again and again I see developers using doubles for storing financial data (e.g. monetary figures, interest rates etc.). This always causes some sort of rounding issue down the line.

try this in your IDE:

double total = 0;
for (int i =0; i < 10; i++){ total += 0.1; } System.out.println(total); [/source] If you expect the answer to be 1 or 1.0, then you're wrong ! Question: are you writing a game ? Answer: no; then use an effing BigDecimal! Grrr...

Advertisements

Using Hibernate Search in SEAM 2.0 Application

I implemented hibernate search recently in a SEAM project I was working on. I wanted to use the excellent suggestion tag from the excedel library and I wanted to use an index rather than hitting the database for each of the searches. I also wanted to use wildcard searches and for each keystroke this would be far to expensive. To implement it I completed the following steps: –

In my persistence.xml I added the following to the properties of my persistence-unit:-

<property name="hibernate.search.default.indexBase" value="PATH TO YOUR INDEX DIRECTORY"/>
<property name="hibernate.ejb.post-insert" value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.post-update" value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.post-delete" value="org.hibernate.search.event.FullTextIndexEventListener"/>

The path of your index base can be anywhere you want as long as the application has permission to write to it.

To used hibernate search you need to identify and highlight all of the classes that you want to search, you also need to identify each of the properties that you want indexed and the indexing strategy, you can find out what the various types are here Hibernate Search

@Indexed(index="index_direcory")
public class SomeClass

@Field(index=Index.TOKENIZED, analyzer = @Analyzer(impl = LowerCaseAnalyser.class))
@Column(name = "inv_name", length = 200, nullable = true)
private String name;

Inject an instance of FullTextEntityManager into your code. I used a stateless session bean that was used throughout the application

@In
private FullTextEntityManger entityManager;

I used a three different query types, RegEx, Prefix and WildCard.

RegexQuery(new Term(fieldName,".*[^-'\\w]" + searchString.toLowerCase() + "(\\s|$)"));
PrefixQuery(new Term(fieldName,searchString.toLowerCase()));
WildcardQuery(new Term(fieldName,'*'+searchString.toLowerCase()+'*'));

The regex one was used to search for firstname surname i.e. Jo Bloggs. The prefix query was used to search for Jo* i.e. Joanne, Jo Bloggs. The wildcard one, the most expensive one, was used to search for *Jo* i.e. Jones, BillyJoBloggs. The fieldname is the obviously the name of the field, so in:-

@Field(index=Index.TOKENIZED, analyzer = @Analyzer(impl = LowerCaseAnalyser.class))
private String name;  

FiledName would = name

All that is left to do it actually query the index and this is done by:

entityManager.createFullTextQuery(query,SomeClass.class).getResultList();

This has been in production for a some time now and it’s been stable and performed well. There has only been one instance to date of the index getting screwed up but I catered for that and enable the index to be rebuilt. I also had to provide this as any update to the indexed fields via direct sql wouldn’t be updated.

Passionate About Programming

Today I bought The Passionate Programmer from the Pragmatic Bookstore; this is the 2nd Edition of My Job Went to India: 52 Ways to Save Your Job and has been re-targeted more clearly at becoming an ‘awesome developer’ rather than ‘doing enough to not get fired’ which the earlier title implied. While buying this I was distracted by a post on The Pragmatic Life blog called Share Your Passion which inspired me to share what it is that makes us (the bloggers here) passionate about developing software. BTW: So far the book is great – thanks Chad.

There is synchronicity at play here; when we started this blog the other day we were toying with subtitles and one of the ones we considered seriously was a tongue in check ‘awesomeness codified’ (personally I still like this the best even though I didn’t come up with it :-P). Part of the reason we started this blog is to put stuff out in the public domain to get feedback. To reach out to people who know and understand more than us in the public domain and to share what we’ve found to those close behind us on the curve. We are hoping to get the sort of feedback that will help us move closer to ‘awesomeness’ in software development. We also want to have a place to whinge about things we find annoying :-P.

Each of us is near the top of the chain in our organisation; we have broad and deep skills in many areas of the Java and Java EE space and have been around the block many times in both successful and failed projects; we’ve been shouted at, we’ve worked all night, gotten depressed and received accolades and glory. Also, a large part of our experience has been in banking – which has it’s own world of pain points but can also be a glorious industry to work in for a software developer.

Obviously you take the good with the bad – but how have we kept our heads above water (psychologically) during the bad times – it is because we are passionate about what we do and deep down we are still enjoying the cut and thrust of software development it even when the poo is hitting the fan.

We were discussing recently how much we enjoyed one night a few years ago where we were in the office all night and most of the next day (after a full days work too) because of the intensity of the situation that the business was in. Basically we received in one night far more volume than was expected and we had to ‘massage’ it through systems that were in their infancy and in no way ready to scale to the level of data we had to process. Regardless of how we got into this situation (obviously in an ideal world we might have planned better) we had to now manage it and were on the critical path of a successful or failed year end process (i.e. make or lose lotsa money). This meant that we had some very senior executive director level people in the business right down to the current season of graduate interns and us all working as a unit, in the zone, to get over the line. It was stressful, difficult and tiring but we felt a part of something; we were able to display skills and aptitudes in a very visible way and deliver results instantly, not just the results in managing overburdened systems but in joining business decisions using peripheral skills gained in building software for the business we were a part of. It was an environment of mutual trust and respect with everybody intensely focused on a positive outcome regardless of position or role in the business. This is awesomeness codified.

Anyway, back to the point – we want to become ‘awesome developers’. This doesn’t mean ‘they who know the most api calls in the java.lang package’ or ‘they who can make JBoss sing the national anthem – in a language of your choice (while washing the dishes)’*; it means we want to love what we are doing and to inspire others (in the space) to love what they are doing; it means we want to be able to deliver robust, reusable, reliable and ‘awesome’ solutions better and better every time; it means we accept that someone will always know more than us and that we will strive to meet those people that we might incorporate what they know into delivering better and better solutions; it means we want to be a part of and understand the businesses we work with and within, again so we can deliver better and better solutions; it means we want colleagues (it & business) to say ‘wow, they really care about what they do’.

So this is why we blog. We want the feedback; we want to attract developers who are already awesome – though they may not know it – to help us improve. However, to be brutally honest maybe we just want to be famous :).

* we can though, well – maybe not the dishes bit.

Calling Stored Procedures in JPA

Recently I had to call a stored procedure using JPA and to my surprise I soon found out that it’s not directly supported. So how do you call a stored procedure? My stack is

Db = Sybase
AppServer = JBoss 4.2.3
Java = 1.6
Persistance = EJB3 implemented by Hibernate
Hibernate = 3.4.0.GA

So the first thing I do is to create a named native query on my entity which looks something like this:

@NamedNativeQuery(name="StoredProc_Call",
                  query="stored_proc_name(:param1, :param2, :param3)",
                  hints={
                      @QueryHint(name = "org.hibernate.callable",value = "true"), 
                      @QueryHint(name = "org.hibernate.readOnly",value = "true")
                  },
                  resultSetMapping="scalar", resultClass=Result.class)

@SqlResultSetMapping(name="scalar",columns=@ColumnResult(name="result")

Because I’m using hibernate as my EJB3 implementation, the default for JBoss, I can use it to call the stored proc for me using the hints attribute which takes in an array of queryhint objects.

Because native scalar results aren’t supported by EJB3 you also have to set the resultClass and the resultSetMapping.

@SqlResultSetMapping(name="scalar",columns=@ColumnResult(name="result")

All that is required now is to create the native query, set the required parameters and call it.

Query query = entityManager.createNamedQuery("StoredProc_Call");

MS Word for Mac – Hate the Toolbox

Is it just me or is the toolbox in MS Word 2008 for Mac ridiculously small (read: horrid). I’m battling with a document with many styles at the moment and am finding myself scrolling up and down, up and down endlessly in a scroll window that displays 5 styles at a time. I’ve got RSI just thinking about it.

On a lighter note – I’m lovin’ the new Ribbon concept in the Windows version. Who ever designed that deserves a pat on the back (and a big bonus). It takes a little getting used to but is just great when your up the learning curve.

If there is some friendly competition between the Word for Mac and the Word for Windows UI teams then I think the Windows team well and truly wins this round.

Jon

PS: If anyone knows how to increase the size of the toolbox or dock it please tell me how. Please – I’m dying here.

Non-anaemic models and service oriented architectures

The term “anaemic domain model” is used to describe an entity layer that contains very little business logic. Typically in this architecture, the business logic is contained in services and/or delegates. There are several problems with this approach:

  • Business logic quickly gets scattered and duplicated across the system
  • It is difficult to maintain because it is hard to determine which class needs to be changed
  • It is difficult to test because the service/delegate usually has many dependencies
  • It is not particularly object oriented (e.g. polymorphism, which can reduce a lot of complexity by reducing ‘type-logic’, is rare)

The trend these days is towards Domain Driven Design (DDD), and is a strategy against anaemic domain models. In this architecture, services are used as an ‘anti-corruption-layer’ to translate requests from the external domain to the internal domain of the system. The majority of the logic is contained within the domain model (this includes persistent and non-persistent objects).

When developing a non-anaemic model (e.g. DDD), it is tempting to call services directly to perform logic (to perhaps an external system, or send a message), to hide complexity from the client:

class Account {
    Balance getBalance() {
        for(Transaction t : getTransactionService().getTransactions(…)){
            //… sum them up
        }
    }

    TransactionService getTransactionService() {
        // lookup service
    }
}

I think this not good design for a number of reasons:

  • The risk of Leaky Abstraction (e.g. having to declare checked Exceptions to methods)
  • Generally speaking, the domain model doesn’t have enough information about the nature of the method call to perform well. The service would be better suited to know how the model will be used (e.g. in a loop).
  • It is harder to test the business logic because you’ve got to mock out too many dependencies.
  • I believe that entities should be deterministic, the behaviour must be determinable given the state of the system/database.
  • Potentially introduces circular dependencies between service->model->service->model etc. which causes problems for maintainability, testing and debugging.

So how do we have a nice, clean, rich domain model ? One way is to pass an implementation of an interface to the domain (e.g. a delegate to a service) so the domain can perform its logic:

class Account {
    Balance getBalance(TransactionRepository repos) {
        // … get the transactions, sum them up
    }
}
// Getting the balance on a single account
Account account =...;
account.getBalance(singleAccountTransactionRepository);
// Getting the balance on many accounts
List<Account> accounts = ...;
for(Account account : accounts){
          account.getBalance(allAccountTransactionRepository);
}

The idea here is that you substitute the most appropriate implementation to get the best performance for the particular use case.

There is a subtle difference between the two, but the second IMO is a cleaner, more-flexible solution.

Re: A general approach to exceptions in Java

My previous post about exceptions in Java begs the question: Where do so called “business exceptions” fit in with all of this?

Business Exceptions are Checked Exceptions

Following on from my reasoning, the user is something that you have no control over. Therefore you expect these types of exceptions to occur. Making them checked exceptions forces you to handle them in some way.

A classic example of these errors are validation errors. These should be checked exceptions because usually you’d need to force the user to fix the entered data before the form can be submitted.

Dealing with Checked Exceptions

The problem of checked exceptions is: how do you handle them ? You’ve got to catch them somewhere (or rethrow), how do you know what to do with them ? This is usually a requirements question; this should be a hint to you to go back to the business and get some clarification on the requirements.