Working with complex objects in Prevayler commands
The demos included in the Prevayler distribution show how to pass in a couple strings (or something simple like that) into a command constructor in order to create or update an object. The problem is that I have an object called MyObject that has a lot of fields. If I had to pass all of them into the CreateMyObject command manually, it would be a pain.
So an alternative I thought of is to pass my business object itself into the command, but to hang onto a clone of it (keeping in mind that I can't store the BO directly in the command). Of course after executing this command, I would need to make sure to dispose of the original copy that I passed in.
public class CreateMyObject 开发者_StackOverflowimplements TransactionWithQuery {
private MyObject object;
public CreateMyObject(MyObject business_obj) {
this.object = (MyObject) business_obj.clone();
}
public Object executeAndQuery(...) throws Exception {
...
}
}
The Prevayler wiki says:
Transactions can't carry direct object references (pointers) to business objects. This has become known as the baptism problem because it's a common beginner pitfall. Direct object references don't work because once a transaction has been serialized to the journal and then deserialized for execution its object references no longer refer to the intended objects - - any objects they may have referred to at first will have been copied by the serialization process! Therefore, a transaction must carry some kind of string or numeric identifiers for any objects it wants to refer to, and it must look up the objects when it is executed.
I think by cloning the passed-in object I will be getting around the "direct object pointer" problem, but I still don't know whether or not this is a good idea...
Cloning doesn't help you with the baptism problem, unless you make sure that the original object has no references to other objects. But that is a different problem than what you described.
If you don't want to write so many createCommands, pass in a Dictionary of name-value pairs and a key to the class to create.
I have never used Prevayler and I'm not sure if I understand your problem, but I think You gave yourself an answer:
Direct object references don't work because once a transaction has been serialized to the journal and then deserialized for execution its object references no longer refer to the intended objects - - any objects they may have referred to at first will have been copied by the serialization process
In CreateMyObject keep uniqe identifier of MyObject. Not a reference. Cloning has nothing to do here.
精彩评论