just in case anyone else has this issue, thought i'd lay out my solution - may not work for a lot of people, but worked in my case.
Originally I had this
Code:
<property name="income" type="MoneyCurrency">
<column name="income"/>
<column name="currency"/>
</property>
<property name="previousYearIncome" type="MoneyCurrency">
<column name="previousYearIncome"/>
<column name="currency" />
</property>
the moneyCurrencyType must map onto a column for the amount of money, and one for its currency.
The front end will
either have income OR previousYearIncome -
never both! So we did not want to make a previousYearCurrency field in the DB, and it is reasonable to have the currency db field for both.
I could find no way to conditionally change the column names at runtime (i.e, only use the 'income' block, but sometimes it maps to income, and sometimes to previousYearIncome)
My solution was to decouple the amount and currency, using new, private variables, so:
Code:
<property name="incomeValue" type="java.lang.Double">
<meta attribute="scope-set">private</meta>
<column name="income"/>
</property>
<property name="previousYearIncomeValue" type="java.lang.Double">
<meta attribute="scope-set">private</meta>
<column name="previousYearIncome"/>
</property>
<property name="currency" type="java.lang.String">
<meta attribute="scope-set">private</meta>
<column name="currency"/>
</property>
and then provide getters and setters to the original variables
Code:
<meta attribute="class-code">
/** income getter */
public Money getIncome() {
double income = incomeValue == null ? 0d : incomeValue.doubleValue();
CurrencyEnum currency = CurrencyEnum.getEnum(this.currency);
return new Money(income, currency);
}
/** previousYearIncome getter */
public Money getPreviousYearIncome() {
double previousYearIncome = previousYearIncomeValue == null ? 0d : previousYearIncomeValue.doubleValue();
CurrencyEnum currency = CurrencyEnum.getEnum(this.currency);
return new Money(previousYearIncome, currency);
}
/** income setter */
public void setIncome(Money income) {
this.incomeValue = new Double(income.getAmount());
this.currency = income.getCurrency().getName();
}
/** previousYearIncome setter */
public void setPreviousYearIncome(Money previousYearIncome) {
this.previousYearIncomeValue = new Double(previousYearIncome.getAmount());
this.currency = previousYearIncome.getCurrency().getName();
}
</meta>
note, these are no longer getters and setters exactly, as they don't represent a class variable - there is no 'Money income' variable - only the method to construct it.
This lets the java continue to use Money income & Money previousYearIncome, but hibernate only uses the separate incomeValue, previousYearIncomeValue, and currency values.