I want to save an xml datatype using jpa in the database(Postgres entity), i have created a converter which read the data from the xml column and create a field from this data . the problem is that eclipse link is mapping the data to var char instead of xml and generate error if change the column type to xml so how to tell jpa that the data type of the converter is xml and not the classical default datatypes. Edit code: Converter:
@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
+ "]";
}
} Money
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 + "]";
}
}