Let me walk you through my reasoning:
Class methods
Basic principle: Persistance is a class behaviour and should be a class method
You need separation of concerns, so you put the database nitty-gritty in a DAO class, and use that from the class to implement the methods.
First problem: if you need to support different sets of DAOs you need to create them through a Factory.
Second problem: not all persistence behaviours are specifically related to an instance of the class. For example List and Search methods: they return Class lists, not classes, and do not depend on an instance. So they are fundamentally static methods.
Third problem: you want to support inheritance on this class. As such, the persistence details differ from parent to child. If you have static methods, it's going to be a problem.
So you move on to the
Controller
Basic principle: Persistence methods do not belong to a single class, they are larger and thus they should be separated
Separation of concerns is needed again, so you need DAOs. This is a Utility class so methods are all basically static.
First problem: you need a Factory to create the DAOs if you want to support more than one persistence method.
Second problem: you want to support a hierarchy of Classes so you can't use a static class. You need to generate the Controllers through a Factory.
Third problem: you are offering an overcomplicated API to your developers.
Example of client code:
PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);
then I would start from scratch.
Start from behaviours
Basic principle: Persistence is not a behaviour. Behaviours are larger than persistence.
In your system there will be a Purchase Order subsystem. Your user will be able to interact with it only at high level (use case level). So,the methods will implement Purchase Order use cases. These methods will use DAOs, through a factory if needed, to access the database and do whatever they need to do.
In short, your PurchaseOrder is basically a DTO, a quick way of passing data around. It should not have behaviours.
Example of client code:
// It could be a factory if needed.
PurchaseOrderSystem pos = new PurchaseOrderSystem();
List<PurchaseOrder> transacted;
transacted = pos.TransactPurchaseOrders(john, 23);
// Show transacted purchase orders or whatever...