Let's say you have a class that writes a string to the database. You abstract out the actual writing to the database of this string thinking it's always going to work, it's just dumping data after all. Your test passes, everything is good.
Now you optimize your database and add a restriction to make the string at most 50 characters. Your test still passes, but you now have a bug. OK, so you should've had a restriction in your BO. You add that restriction and move on.
Your DBA comes along and adds an integrity check or a trigger that makes the insertion fail if some weird condition is met. Your test passes, but you have a bug.
This can get even more interesting when you hit some basic database rule that you didn't even know it existed. You assume the insertion will work, but it won't. You now have a bug.
You've tested that 2 + 2 = 4, and it works, but when that code is linked with the actual database you realize that in some cases 2 + 2 doesn't equal 4.
I'm not saying don't have unit tests, but when it comes to bugs, the fast majority of these bugs, in my experience, come from the glue, from the assumption that the piece you're integrating with should work one way, but reality begs to differ.