When you retrieve from the cache by id (getOrderItemById) I'd assume that to mean "get the object uniquely identified by id=?". In your second excerpt you have (or are trying to have?) 2 different objects so it looks a bit like you're trying to do 2 contradictory things in the code.
You could enforce uniqueness-Id="ID" is always the same object. If you set the status and then reset it, it means the same object has new status. You'd probably want to extend the .equals method to return true if the id matches as well.
You could also use a "dirty" flag to mark objects that have been changed from the (transactional?) data store.
Making a copy is not a bad way to deal with this either, though it's not clear what it means to have 2 objects running around with the same id. Maybe the copy should be created with a null id to indicate that it doesn't exist in the cache yet?
What's the right behavior for your application?