我有两个实体ValCurs
和Valute
,我们可以映射远程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
获取date
和ValCurs
,但我无法实现(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>
答案 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);