Here are my suggestions:
- Try to get rid of the least used functionality. Question the features that are not used all the time. Each feature in an application has several levels of costs associated with it (maintaining, support, regression testing, code complexity, etc.).
- Stay away from Stored procedures, unless there is absolutely no way to do it efficiently and in a scalable manner in the code.
- Introduce an ORM solution gradually (using refactoring to move from JDBC to ORM) to reduce the amount of code and code complexity in CRUD operations
- Build functional, integration and unit tests as and when you fix a bug and incorporate those tests in to the Continuous integration system. Automate your regression testing as much as possible to identify problems as soon as it is introduced by a check-in.
- In general, whenever you fix a bug, use that opportunity to refactor to decouple the implementations/code modules.
If you have have questions about Database migration problems, this might help: http://shashivelur.com/blog/2008/07/hibernate-db-migration/