computed field and Hibernate
Remind me: how do I map a Java class with a computed field that should be persisted? I.e.:
public class PolicyHolder {
private int height;
private int weight;
private boolean smoker;
private boolean exerciser;
// getters and setters for those properties omitted for开发者_StackOverflow brevity's sake.
public int getLifeExpectancy() {
return Utilities.computeBMI(height, weight) + (smoker ? 0 : 20) + (exerciser ?20 : 0);
end;
}
I've got my business logic in Java there in getLifeExpectancy(), and I'm going to call it sometimes from Java. But I also want the value persisted along with the rest of the PolicyHolder. How can I map this class using Hibernate?
The way that I've done this in the past (although I don't like persisting computed values) is to have the getter for the value just return a field and have all of the other fields that impact the computed value recompute it every time they change. Doing this you can just tell hibernate to persist the computed field.
public class PolicyHolder {
private int height;
private int weight;
private boolean smoker;
private boolean exerciser;
private lifeExpectancy; //Tell hibernate to persist this field
// getters omitted for brevity's sake.
public void setHeight(int aHeight) {
height = aHeight;
computeLifeExpectancy();
}
public void setWeight(int aWeight) {
weight = aWeight;
computeLifeExpectancy();
}
public void setSmoker(boolean aSmoker) {
smoker = aSmoker;
computeLifeExpectancy();
}
public void setExerciser(boolean anExerciser) {
exerciser = anExerciser;
computeLifeExpectancy();
}
public int getLifeExpectancy() {
return lifeExpectancy;
}
/**
* Computes and saves the life expectancy.
*/
private void computeLifeExpectancy() {
lifeExpectancy = Utilities.computeBMI(height, weight) + (smoker ? 0 : 20) + (exerciser ?20 : 0);
}
}
Note: A big downside to this approach (in my opinion) is that all of the setters now have a side effect (ie. doing more than just setting the value they say they are setting).
精彩评论