我想在数据库中使用jpa保存xml数据类型(Postgres实体),我创建了一个转换器,它从xml列读取数据并从该数据创建一个字段。问题是eclipse链接将数据映射到var char而不是xml,如果将列类型更改为xml则生成错误,以便告诉jpa转换器的数据类型是xml而不是经典的默认数据类型。 修改 代码: 转换器:
@Converter(autoApply=true)
public class MoneyConverter implements AttributeConverter<Money, String> {
@Override
public String convertToDatabaseColumn(Money arg0) {
if (arg0 == null)
return null;
else {
String outputXml = "";
for (String currenctCode : arg0.getOutput().keySet()) {
outputXml += "<"
+ currenctCode
+ ">"
+ arg0.getOutput().get(currenctCode).getMoneyValue()
.toString() + "</" + currenctCode + ">";
}
return "<money><input><"
+ arg0.getInput().getCurreny().getCurrencyCode() + ">"
+ arg0.getInput().getMoneyValue().toString() + "</"
+ arg0.getInput().getCurreny().getCurrencyCode()
+ "></input><output>" + outputXml + "</output></money>";
}
}
@Override
public Money convertToEntityAttribute(String arg0) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
if(arg0!=null)
{
try {
db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(arg0));
Document doc = db.parse(is);
Element root = doc.getDocumentElement();
Node input = root.getElementsByTagName("input").item(0);
MoneyEntry inputEntry = new MoneyEntry(input.getChildNodes().item(0).getNodeName(),
BigDecimal.valueOf(Double.valueOf(input.getChildNodes().item(0).getTextContent())));
Map<String, MoneyEntry> outputEntries = new HashMap<>();
Node output = root.getElementsByTagName("output").item(0);
for (int i = 0; i < output.getChildNodes().getLength() - 1; i++) {
Node child = output.getChildNodes().item(i);
MoneyEntry outputEntry = new MoneyEntry(child.getNodeName(),
BigDecimal.valueOf(Double.valueOf(child
.getTextContent())));
outputEntries.put(child.getLocalName(), outputEntry);
}
return new Money(inputEntry, outputEntries);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
return null;
}
}
MoneyEntry
public class MoneyEntry implements Serializable{
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private Currency curreny;
private BigDecimal moneyValue;
public MoneyEntry(String currencyCode) {
currencyCode=currencyCode.toUpperCase();
System.out.println(currencyCode);
this.curreny = Currency.getInstance(currencyCode);
}
public MoneyEntry(String currencyCode, BigDecimal value) {
this(currencyCode);
this.moneyValue = value;
}
public BigDecimal getMoneyValue() {
return moneyValue;
}
public void setMoneyValue(BigDecimal moneyValue) {
this.moneyValue = moneyValue;
pcs.firePropertyChange("moneyValue", this.getMoneyValue(), moneyValue);
}
public Currency getCurreny() {
return curreny;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
@Override
public String toString() {
return "MoneyEntry [curreny=" + curreny + ", moneyValue=" + moneyValue
+ "]";
}
} 货币
public class Money implements Serializable, PropertyChangeListener {
private MoneyEntry input;
private Map<String, MoneyEntry> output = new HashMap<>();
public Money(String inputCurrencyCode) {
input = new MoneyEntry(inputCurrencyCode);
input.addPropertyChangeListener(this);
}
public Money(String inputCurrencyCode, BigDecimal inputValue) {
input = new MoneyEntry(inputCurrencyCode);
input.setMoneyValue(inputValue);
computeOutput();
input.addPropertyChangeListener(this);
}
Money(MoneyEntry input, Map<String, MoneyEntry> output) {
this.input = input;
this.output = output;
input.addPropertyChangeListener(this);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
computeOutput();
}
// will be changed to compute output by using static field , that filled by the money configuration
// singelton
private void computeOutput(){
output.clear();
for(CurrencyConfigurtionTransferObject currencyConfigurtionTransferObject:CurrencyConfigurationHolder.getConfigurations())
{
double minorValue=currencyConfigurtionTransferObject.getMinorValue();
double majorValue=currencyConfigurtionTransferObject.getMajorValue();
double ratio=minorValue/majorValue;
output.put(currencyConfigurtionTransferObject.getMinorCurrency().getCurrency(), new MoneyEntry(currencyConfigurtionTransferObject.getMinorCurrency().getCurrency().toUpperCase(), BigDecimal.valueOf(input.getMoneyValue().doubleValue()*ratio)));
}
}
public MoneyEntry getInput() {
return input;
}
public Map<String, MoneyEntry> getOutput() {
return output;
}
@Override
public String toString() {
return "Money [input=" + input + ", output=" + output + "]";
}
}