Sounds like a job for a Design
Pattern. You could manage the interface between the program and
JDBC bits with an extra level of abstraction - ie it could be viewed as a Decorator for the JDBC bits.
The 'online' bits stay the same, but create a 'Persistence Manager' that wraps around it. When called, the PM checks for a valid network connection. If this succeeeds, it provides a direct interface to the old JDBC code. Otherwise, it invisibly caches the data in the local version for later on.
This solves points 1 and 3. To solve part two, you can have the PM also detect the fact that a connection didn't exist but now daoes and can replicate data back. Or this could be a separate process.
There will be a problem with managing unique keys, but a solution I like is to have each client process have the 'high bits' predetermined, and be allowed to set the 'low bits' itself. eg the local client might have a 'local key base' of 0110-0000 (this is just an 8-bit example) and is then free to allocate all keys from 0110-0000 to 0110-1111.
Now I've thrown this out (from the top of my head, so be gentle

) Arguments?
Dave