"Abstract over data, not behaviour"
This seems to fall into the trap of abstracting over behaviour.
The best other example I've thought of for this is the 'generic repository pattern' common in C# and I'd guess Java. Just because CRUD on types is all similar behaviour you can't really build a generic/abstracted way of doing it, because at some point you need different behaviour in some update/insert depending on how the domain concept should act and then you're in a world of pain with a crappy abstraction.
One's code actually 'doing something' isn't a sign of unclean code, it's why one writes it. Stop trying to build abstractions that simplify the doing of what your code does.