The idea is to use a Generic Entity Value Object, that contains all logic to handle updates and concurrency for your entity beans.
Follwing Class hierarchy is proposed:
1. abstract EntityValueObject
2. SpecificValueObject extends EntityValueObject
3. SpecificEntityBean extends SpecificValueObject.
The EntityValueObject is an abstract class that contains all logic for updates and concurrency, the SpecificValueObject is used to transfer data to and from clients of entity beans and the SpecificEntityBean represents the Bean implementation.
As previously stated the EntityValueObject contains all logic for updates and concurrency, represented by following methods:
- EntityValueObject genericCreate (EntityValueObject obj)
- EntityValueObject update (EntityValueObject obj)
- EntityValueObject forceUpdate (EntityValueObject obj)
- int getVersion()
- void setVersion(int version)
The genericCreate method is used to construct a new entity from a Value Object, this method will be called by the ejbCreate method of the entity bean.
The update method takes a Value Object as argument and returns a Value Object with an updated version number.
The forceUpdate can be used to force an update if a user tries to update data that has already been modified by someone else. The getter and setter methods for the version are used for concurrency control.
Reflection to the rescue
You might wonder how this works. The secret is reflection. Whenever you update a bean by passing it a Value Object, it will inspect all attributes of the Value Object and update the corresponding bean attributes with their values. It will also check whether the version number of the value object is different from the bean's version number, if this is the case, it will throw an exception which indicates that the bean has been updated by another client.
Here is a code snippet of the update method:
//Allow the update of 'id' if 'this.id == null', because the
//ejbcreate-methods use this update() method.
if (!((this.id == null) || (this.id.equals(obj.id)))) {
setRollbackOnly();
throw new IllegalUpdateException("Changing the id of a bean is not allowed!");
}
//Test if the data is stale (obj.getVersion() != this.getVersion())
if (obj.getVersion() != this.getVersion()) {
setRollbackOnly();
throw new ModifiedException("Data has been modified before your change has been commited!");
}
//update all fields.
Class beanClass=this.getClass();
Class voClass= obj.getClass();
try {
Field[] voFields = voClass.getFields();
for (int i=0;i<voFields.length;i++) {
if (!(voFields[i].getName().equals("id"))){
beanClass.getField(voFields[i].getName()).set(this,voFields[i].get(obj));
}
}
//update the version nbr
int currentversion=this.getVersion();
currentversion++;
setVersion(currentversion);
//return the object
return this.asValueObject();
}
catch (Exception e) {
...
}
Let's consider the following example, imagine a business object called "Person" that you want to implement as an Entity Bean.
The first thing you will do is create a PersonValueObject with the attributes that belong to a person, e.g. name, date of birth, address, gender, telephone, etc..
All attributes that you want to persist should be declared public. This Value Object must extend EntityValueObject.
Next thing will be creating the Entity Bean PersonEntityBean, which will extend the PersonValueObject. Basically, you don't have to implement much except for the ejbCreate method that will call the genericCreate method of the EntityValueObject. That's it, you don't need to implement any other methods. You can now deploy and start using your entity bean.
-
Generic Entity Beans (12 messages)
- Posted by: Edwin Mol
- Posted on: September 12 2002 15:20 EDT
Threaded Messages (12)
- Generic Entity Beans by Marcio Antonio Alves on September 12 2002 17:57 EDT
- Generic Entity Beans by Pee Wee on September 13 2002 02:33 EDT
- Generic Entity Beans by Marcio Antonio Alves on September 13 2002 11:36 EDT
- Generic Entity Beans by Kent Smotherman on September 16 2002 18:18 EDT
- Generic Entity Beans by Pee Wee on September 17 2002 01:08 EDT
- Reflection performance problems by Antti Valtokari on September 19 2002 00:27 EDT
-
Reflection performance problems by Web Master on September 19 2002 06:04 EDT
-
Reflection performance problems by John Harby on September 19 2002 06:59 EDT
-
EJB fordibs using Reflection API? by Antti Valtokari on September 20 2002 04:28 EDT
-
EJB fordibs using Reflection API? by John Harby on September 21 2002 10:45 EDT
-
EJB fordibs using Reflection API? by Tobias Rademacher on October 28 2002 03:46 EST
- EJB fordibs using Reflection API? by Jens Schumann on November 04 2002 10:12 EST
-
EJB fordibs using Reflection API? by Tobias Rademacher on October 28 2002 03:46 EST
-
EJB fordibs using Reflection API? by John Harby on September 21 2002 10:45 EDT
-
EJB fordibs using Reflection API? by Antti Valtokari on September 20 2002 04:28 EDT
-
Reflection performance problems by John Harby on September 19 2002 06:59 EDT
-
Reflection performance problems by Web Master on September 19 2002 06:04 EDT
- Generic Entity Beans by Pee Wee on September 13 2002 02:33 EDT
-
Generic Entity Beans[ Go to top ]
- Posted by: Marcio Antonio Alves
- Posted on: September 12 2002 17:57 EDT
- in response to Edwin Mol
The problem of reflection is performance. But if performance isn't important then there is a strategy for Value Objects that enhance your pattern. The Value Object Factory Strategy uses reflection to create VO based on the class name. Then you only need to inform the Class of VO.
This pattern is described in the book Core J2EE patterns. -
Generic Entity Beans[ Go to top ]
- Posted by: Pee Wee
- Posted on: September 13 2002 02:33 EDT
- in response to Marcio Antonio Alves
And just how often are performance not important... -
Generic Entity Beans[ Go to top ]
- Posted by: Marcio Antonio Alves
- Posted on: September 13 2002 11:36 EDT
- in response to Pee Wee
I think that the performance of reflection in Java must be improved. The version 1.4 improves it a little. The Pattern is valid. A pattern must not go to trash only by the fact that the actual programming languages don't perform well with it. The languages must be improved to support the patterns. Not vice-versa. If the pattern don't perform well then choose another pattern until the language be improved. -
Generic Entity Beans[ Go to top ]
- Posted by: Kent Smotherman
- Posted on: September 16 2002 18:18 EDT
- in response to Marcio Antonio Alves
Well if you really cared about performance I don't think you'd be useing EJBs at all! But, that's another topic :) Given the huge overhead just to use EJBs (especially EJB 1.1) the overhead of reflection is fairly trivial.
Anyway, that's all IMHO :)
Kent -
Generic Entity Beans[ Go to top ]
- Posted by: Pee Wee
- Posted on: September 17 2002 01:08 EDT
- in response to Kent Smotherman
You are so right. That is why one use BMP with DAO and make use of the DAO for listing and the bean for updating. :) -
Reflection performance problems[ Go to top ]
- Posted by: Antti Valtokari
- Posted on: September 19 2002 00:27 EDT
- in response to Marcio Antonio Alves
I have used similar approach for JavaBeans in the past. The performance for reflection-based solution was not that bad compared to the total round-trip time required to process an incoming HTTP-request. However the difference to compiled Java class doing the same thing was something like 100 times.
Because of this difference I wondered if it would be possible to create an utility that generates the Java-code for bean/value object manupulation on run-time and compiles this code to be the class to use for manipulation? Since this needs to be done only once the time required for compiling is taken only once (like for JSPs that are not precompiled). After that the generated class can be reused until the JVM is shut down. Unfortunately there was no time to try this but has someone else tried this kind of approach? -
Reflection performance problems[ Go to top ]
- Posted by: Web Master
- Posted on: September 19 2002 06:04 EDT
- in response to Antti Valtokari
Doesnt JBoss do something like this to dynamically generate stubs and ties for it beans? -
Reflection performance problems[ Go to top ]
- Posted by: John Harby
- Posted on: September 19 2002 18:59 EDT
- in response to Web Master
The EJB spec forbids using reflection in EJBs (sec. 25.1.2)
"The enterprise bean must not attempt to query a class to obtain information about the declared
members that are not otherwise accessible to the enterprise bean because of the security rules
of the Java language. The enterprise bean must not attempt to use the Reflection API to access
information that the security rules of the Java programming language make unavailable." -
EJB fordibs using Reflection API?[ Go to top ]
- Posted by: Antti Valtokari
- Posted on: September 20 2002 04:28 EDT
- in response to John Harby
My English is limited since it is not my mother tonque but I understand that part so that using Reflection API as such is not forbidden but using it to bypass Java language security rules is forbidden. Getter/setter methods are (or should be) public and therefore I see no problem to use Reflection API to query them on EJBs. -
EJB fordibs using Reflection API?[ Go to top ]
- Posted by: John Harby
- Posted on: September 21 2002 10:45 EDT
- in response to Antti Valtokari
You are correct the wording there is left to some possible interpretation. I will post a question to EJB-INTEREST on this. -
EJB fordibs using Reflection API?[ Go to top ]
- Posted by: Tobias Rademacher
- Posted on: October 28 2002 03:46 EST
- in response to John Harby
Hi Guys,
due to currently avaialbe implementation of Aspect Orient Programming (AOP) rely on Reflection API. It would be awfull to
prohibit this by specfication.
I agree in everything said about performance, but I guess throwing away Reflection API would be totaly stupid. You lose to much flexilbity.
Sure XDoclet helps to avoid monton coding of getter/setter stuff, but Metaprogramming isn't so dynamic as sometimes necessary.
They should worry more about the Classloader's. Are you really sure that a ContainerProvider implemenend it's Classloader safely?
Cheers
Toby -
EJB fordibs using Reflection API?[ Go to top ]
- Posted by: Jens Schumann
- Posted on: November 04 2002 22:12 EST
- in response to Tobias Rademacher
Just read EJB Spec. It has been there since 1.1. The reason for banning reflection is also there.