We eventually sorted this by moving to a Session-per-request paradigm. Not sure why it was going wrong or why this fixed it. I wrote numerous unit tests to try and reproduce the behaviour in a more controlled environment without success.
In any case, it works now. There are good reasons session-per-request is often given as the best practice way to manage NHibernate sessions in a web application.