We do a few tricks:
edit: We do have seperate databases per user. Our buildserver also has it's own database. The cost of extra harddisks is much less than the cost of developers influencing eachother's tests.
- Our application can generate tables and do upgrade steps itself (no seperate db scripts). This helps our customer, because he only needs to drop in a WAR file and he's done. The application looks at the database and carries out any DDL statements needed before starting up the rest of the Spring context.
- Our test-suite has some code which unloads the Spring context, drops the database, and restarts the context with a clean database. We can optionally switch this off if we like
- All our database/SQL unittests are Spring transactional integration tests. This means that after the test is done, the transactions are rolled back, and other unittests will again look at a clean database.
In addition to this all, we try to do mock testing as much as possible, because unittests are really not intended to be integration tests. So try to seperate your servicelayer from the DAO layer. This also helps you find problems more easily because you isolated everything.
At some point I do believe you need to access the database, because it's not an ideal/academic world we live in :-)