我有两个实体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注释技术中的某些东西,我在Java持久性方面确实很新)。附言我正在解析的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>
最佳答案
因此,您在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
CascadeType.CascadeType.ALL大致意味着,如果您插入新的ValCurs,那么其Valutes也将被插入;如果您删除ValCurs,则相应的Valutes也将被删除。 orphanRemoval = true的效果是,如果您从allValutes列表中删除Valuete,它也将从表中删除。
现在,要使关系表示在数据库中,必须在ValCurs及其Valute之间建立链接。最简单的方法是Valute表中的“父”列,其中包含ValCurs的ID。您可以通过添加joincolumn注释来实现:
@XmlElement(name = "Valute")
@OneToMany(cascade=CascadeType.ALL,orphanRemoval = true)
@JoinColumn(name ="VALCURS_ID")
private List<Valute> allValutes; //you should use List rather than
您也可以改用一个联接表(google怎么做)。
我不知道您的valCursService实现,但是使用层叠设置时,您只需要持久保存ValCurs,相关的值将自动保存。
因此在JPA中:
EntityManager em = ...;
em.persist(valCurs); //no need for valuteService.add(valute);
在休眠状态:
Session session = ...;
session.save(valCurs);