解组xml资源后,无法在数据库中存储数据

时间:2015-04-20 10:54:01

标签: java xml hibernate spring-mvc jaxb

我有两个实体ValCursValute,我们可以映射远程xml资源。数据仅存储在Valute实体的数据库中。

以下是我的实体:

ValCurs实体:

@Entity
@Table(name = "valCurs")
@XmlRootElement(name="ValCurs")
@XmlAccessorType(XmlAccessType.FIELD)
public class ValCurs {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

@XmlAttribute(name = "Date")
private String date;

@XmlElement(name = "Valute")
private ArrayList<Valute> allValutes;


public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public ArrayList<Valute> getAllValutes() {
    return allValutes;
}

public void setAllValutes(ArrayList<Valute> allValutes) {
    this.allValutes = allValutes;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

}

Valute实体

@Entity
@Table(name = "valute")
@XmlAccessorType(XmlAccessType.FIELD)
public class Valute {

@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "char_code")
@XmlElement(name = "CharCode")
private String charCode;

@Column(name = "nominal")
@XmlElement(name = "Nominal")
private Integer nominal;

@Column(name = "value")
@XmlElement(name = "Value")
private Float value;

@Column(name = "name")
@XmlElement(name = "Name")
private String name;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getCharCode() {
    return charCode;
}

public void setCharCode(String charCode) {
    this.charCode = charCode;
}

public Integer getNominal() {
    return nominal;
}

public void setNominal(Integer nominal) {
    this.nominal = nominal;
}

public Float getValue() {
    return value;
}

public void setValue(Float value) {
    this.value = value;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

我以这种方式解组:

        URL url = new URL(BNM);
        InputSource is = new InputSource(url.openStream());

        // Converting a XML to java object with JAXB, (UnMarshalling).
        JAXBContext jaxbContext = JAXBContext.newInstance(ValCurs.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        ValCurs valCurs = (ValCurs) jaxbUnmarshaller.unmarshal(is);

        // Extracting the list of Valutes from the root xml
        ArrayList<Valute> listOfValutes = valCurs.getAllValutes();

        // Storing data into database
        for (Valute valute : listOfValutes) {
            valuteService.add(valute);
        }

        valCursService.add(valCurs);

当我运行代码时,它会抛出一个:could not serialize; nested exception 我可以理解为什么(它不能序列化:private ArrayList<Valute> allValutes;在一个表的一个单元格中。)

我需要从id获取dateValCurs,但我无法实现(valCursService.add(valCurs);抛出异常,因此我无法将数据存储在数据库中。)

我的问题是这样的:如何将来自ValCurs的数据存储在一个表格中(也许我在Jaxb注释技术中遗漏了一些东西,我&#39; m在java中持久化真的很新)。

P.S。我正在解析的Xml是这样的:

<ValCurs Date="20.04.2015" name="Official exchange rate">
<Valute ID="47">
<NumCode>978</NumCode>
<CharCode>EUR</CharCode>
<Nominal>1</Nominal>
<Name>Euro</Name>
<Value>19.3441</Value>
</Valute>
<Valute ID="44">
<NumCode>840</NumCode>
<CharCode>USD</CharCode>
<Nominal>1</Nominal>
<Name>US Dollar</Name>
<Value>18.0558</Value>
</Valute>
</ValCurs>

1 个答案:

答案 0 :(得分:1)

因此,您在ValCurls和value之间存在oneToMany关系,您需要通知JPA存储此关系。

缺少的是集合上的@OneToMany注释:

@Entity
@Table(name = "valCurs")
@XmlRootElement(name="ValCurs")
@XmlAccessorType(XmlAccessType.FIELD)
public class ValCurs {    
...    
   @XmlElement(name = "Valute")
   @OneToMany(cascade=CascadeType.ALL,orphanRemoval = true)
   private List<Valute> allValutes; //you should use List rather than ArrayList

cascade = CascadeType.ALL大致意味着如果你插入新的ValCurs,它的Valutes也将被插入,如果你移除ValCurs,那么也将删除相应的Valutes。 orphanRemoval = true的效果是,如果从allValutes列表中删除Valuete,它也将从表中删除。

现在,要在DB中表示关系,必须在ValCurs及其Valute之间建立链接。最简单的方法是Valute表中的“父”列,其中包含ValCurs的id。您可以通过添加joincolumn annotatins来实现它:

   @XmlElement(name = "Valute")
   @OneToMany(cascade=CascadeType.ALL,orphanRemoval = true)
   @JoinColumn(name ="VALCURS_ID")
   private List<Valute> allValutes; //you should use List rather than 

您也可以使用联接表(谷歌如何操作)。

我不知道你的valCursService实现,但是使用级联设置你需要只保留ValCurs并且相关的valute将自动保存。

所以在JPA:

EntityManager em = ...;
em.persist(valCurs); //no need for valuteService.add(valute);

在hibernate中:

Session session = ...;
session.save(valCurs);