Eh, Apex certainly isn't amazing (and the debugging experience is absolutely awful) but the limited code I have to maintain in our org (where workflows and other drag-and-drop tooling weren't sufficient to get the job done) has been quite easy to develop and maintain.
Problems usually come from trying to make applications that aren't well suited to the Salesforce platform work on it natively - it's great for CRUD apps with workflows, a custom visualforce page here or there and some more complicated logic implemented in Apex sprinkled in - but if you are resorting to Apex to do the majority of your work you are likely using the wrong tool for the job.
I've used Apex and I had a completely different experience. The very tight platform integration with force.com, SOSQL, resource management, builtin testing and api framework made it a very productive experience to me. And I say this with a long background in C, C++ and Python.
Having to ship your code back to the mothership to run unit tests made it impossible to run TDD (~30 second overhead on each test run). That along with the test coverage requirements made it a pain on the first level. Unless you're using their utterly abysmal in-browser editor.
On the second level is if you're building an app that needs to talk bidirectionally to salesforce on a per customer (app install) basis. Each salesforce site has their own WSDL URLs. That makes sense if all you're doing is building something out for your own Salesforce site.
But if you're building something installable over their marketplace .... it's almost impossible to have a seamless user experience, from the customer's point of view.
Problems usually come from trying to make applications that aren't well suited to the Salesforce platform work on it natively - it's great for CRUD apps with workflows, a custom visualforce page here or there and some more complicated logic implemented in Apex sprinkled in - but if you are resorting to Apex to do the majority of your work you are likely using the wrong tool for the job.