/
MonetaryAmountType.java
102 lines (84 loc) · 3.47 KB
/
MonetaryAmountType.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.vladmihalcea.hibernate.type.money;
import com.vladmihalcea.hibernate.type.ImmutableCompositeType;
import com.vladmihalcea.hibernate.type.util.Configuration;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.BigDecimalType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.javamoney.moneta.Money;
import javax.money.MonetaryAmount;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import static java.sql.Types.DECIMAL;
import static java.sql.Types.VARCHAR;
/**
* Maps a {@link MonetaryAmount} object type onto two columns (amount and currency).
*
* <p>
* For more details about how to use it,
* check out <a href="https://vladmihalcea.com/monetaryamount-jpa-hibernate/">this article</a>
* on <a href="https://vladmihalcea.com/">vladmihalcea.com</a>.
*
* @author Piotr Olaszewski
*/
public class MonetaryAmountType extends ImmutableCompositeType<MonetaryAmount> {
public static final MonetaryAmountType INSTANCE = new MonetaryAmountType();
public MonetaryAmountType() {
super(MonetaryAmount.class);
}
public MonetaryAmountType(Configuration configuration) {
super(MonetaryAmount.class, configuration);
}
@Override
public String[] getPropertyNames() {
return new String[]{"amount", "currency"};
}
@Override
public Type[] getPropertyTypes() {
return new Type[]{BigDecimalType.INSTANCE, StringType.INSTANCE};
}
@Override
public Object getPropertyValue(Object component, int property) throws HibernateException {
MonetaryAmount monetaryAmount = (MonetaryAmount) component;
if (property == 0) {
return monetaryAmount.getNumber().numberValue(BigDecimal.class);
} else if (property == 1) {
return monetaryAmount.getCurrency();
}
throw new IllegalArgumentException("Invalid property index " + property + " for class " + component.getClass());
}
@Override
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
throw new HibernateException("Call setPropertyValue on immutable type " + component.getClass());
}
@Override
protected MonetaryAmount get(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
String amountColumnName = names[0];
String currencyColumnName = names[1];
BigDecimal amount = rs.getBigDecimal(amountColumnName);
if(amount == null) {
return null;
}
String currency = rs.getString(currencyColumnName);
if(currency == null) {
return null;
}
return Money.of(amount, currency);
}
@Override
protected void set(PreparedStatement st, MonetaryAmount value, int amountColumnIndex, SharedSessionContractImplementor session) throws SQLException {
int currencyColumnIndex = amountColumnIndex + 1;
if (value == null) {
st.setNull(amountColumnIndex, DECIMAL);
st.setNull(currencyColumnIndex, VARCHAR);
} else {
BigDecimal amount = value.getNumber().numberValue(BigDecimal.class);
String currency = value.getCurrency().getCurrencyCode();
st.setBigDecimal(amountColumnIndex, amount);
st.setString(currencyColumnIndex, currency);
}
}
}