Personally, I don't like the idea of using RecordNotFoundException for this. To me, RNFE is a way of saying "that record never existed, or if it did exist, it's been deleted". Not "something unexpected happened and I don't know if the record exists or not". To me, the latter is a different situation, and deserves to be treated as such. Note that the create() and find() methods do not allow RNFE anyway, so some other response must be devised for the case of an IOException during these methods. Once an alternate response is devised, we might as well try to use it for all the cases where IOException is thrown, for consistency.
Personally I think the best response is to wrap the IOException in a RuntimeException (possibly a custom subclass). This can then be caught at a higher level as desired. Probably a GUI user should see a message like:
Your request could not be completed due to an unexplained system error:
[error text]
If this problem persists, please exit and restart the program (notify server mangagement if running over network)
[checkbox] Do not show this message again.
And log the error too, of course.
Regarding the find() method, I don't like the idea of returning an empty array if there's an error. To me, that says "there are no records which match your criteria". Returning null might be slightly better, as that at least sends a different message. But something with more info would be preferable, IMO. And create() doesn't have the option - well, I suppose we could return -1 to indicate an error.
(I'm certainly not using DuplicateKeyExecption to indicate IOException, that's just wrong.) I think it's much better to treat these IOExceptions consistently, in a manner that doesn't hide errors if they occur. RuntimeException seems the best option for this, IMO.