Seam 2.2.2、JSF Mojarra 1.2_13-b01-FCS、JBoss 5.1.0 サーバーを使用しています。
タイプ NUMBER として指定された 3 つの列を持つ Oracle テーブルがあります。生成された hibernate マッピングは、エンティティ クラスのこれらの列を java.math.BigDecimal としてマップしました。これらは通貨の値であり、BigDecimal は Java でこれらの値を格納および計算するための推奨される方法のようです。
数値コンバーターを使用して、画面上の値を h:inputText および h:outputText の通貨として使用しようとしています。Javaが例外をスローしたときに、これらの値の1つを更新しようとするまでは正常に動作します:
EquipItemEdit.xhtml value="#{equipItemHome.instance.cost}": java.lang.IllegalArgumentException: 引数の型が一致しません
私のエンティティは次のようにマッピングされます:
@Entity
@Table(name = "EQUIP_ITEM")
public class EquipItem implements java.io.Serializable {
...
private BigDecimal cost;
...
@Column(name = "COST", precision = 22, scale = 0)
public BigDecimal getCost() {
return this.cost;
}
public void setCost(BigDecimal cost) {
this.cost = cost;
}
...
}
データベース内のテーブル定義
CREATE TABLE EQUIP_ITEM
(
EQUIP_ID NUMBER,
COUNTER NUMBER,
ITEM VARCHAR2(6 BYTE),
ACQADC VARCHAR2(1 BYTE),
COG VARCHAR2(2 BYTE),
COST NUMBER,
NOMENC VARCHAR2(40 BYTE),
QUA_AUTH NUMBER,
...
)
また、フィールドが JSP でどのようにマップされるか:
...
<h:inputText id="cost"
styleClass="value"
value="#{equipItemHome.instance.cost}"
size="15">
<f:convertNumber type="currency" currencySymbol="$" locale="en_US"/>
</h:inputText>
...
何か提案がありますか、または誰かがこのデータ型を処理する正しい方法を教えてくれますか?
今のところ、動作させるために、独自のコンバーターを作成しました。まだ多くのテストを行っていないので、誰かが JSF 組み込みコンバーターをこのために機能させる方法を教えてくれることを願っています。
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
@Name("usDollarsConverter")
@BypassInterceptors
@org.jboss.seam.annotations.faces.Converter
public class UsDollarsConverter implements javax.faces.convert.Converter, Serializable {
public Object getAsObject(FacesContext context, UIComponent component, String string) {
if(string == null) {
return null;
}
try {
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
Object value = nf.parse(string);
if(value instanceof Double) {
value = new BigDecimal((Double)value);
} else if(value instanceof Long) {
value = new BigDecimal((Long) value);
}
return value;
} catch (ParseException e) {
return null;
}
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null) {
return null;
}
if(value instanceof Double) {
value = new BigDecimal((Double)value);
} else if(value instanceof Long) {
value = new BigDecimal((Long) value);
}
if(value instanceof BigDecimal) {
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
return nf.format(((BigDecimal)value).doubleValue());
}
throw new java.lang.IllegalArgumentException("UsDollarsConverter requires a type java.math.BigDecimal, will not work with " + value.getClass().getCanonicalName());
}
}