Java JAXB解组实体-引用为空

Java JAXB解组实体-引用为空,java,xml,jpa,jaxb,unmarshalling,Java,Xml,Jpa,Jaxb,Unmarshalling,我有2个映射类(类似于JPA类): AElement.java @XmlType(propOrder = {"name", "children", }) @XmlRootElement(name = "a") @XmlAccessorType( XmlAccessType.PROPERTY) public class AElement implements Serializable { private String name; private List<BElement> ch

我有2个映射类(类似于JPA类):

AElement.java

@XmlType(propOrder = {"name", "children", })
@XmlRootElement(name = "a")
@XmlAccessorType( XmlAccessType.PROPERTY)
public class AElement implements Serializable {

 private String name;
 private List<BElement> children;

 @XmlElement(name = "metadatum")
 public List<BElement> getChildren(){
    return children;
 }

 ...
}
@XmlRootElement(name = "b")
@XmlType(propOrder = {"name"})
public class BElement implements Serializable{

 private String name;
 private AElement parent;

 ...
}
@Entity
public class A implements Serializable {


 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;

 @Column
 private String name;

 @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "parent")
 private List<B> children;

 public List<B> getChildren(){
    return children;
 }

 ...
}
public void afterUnmarshal(Unmarshaller u, Object parent) {
   this.a = (AElement)parent;
}
A和B是一对一的关系。XML应该如下所示:

<A>
  <B></B>
  <B></B>
</A>
B.java

@Entity
public class B implements Serializable{

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;

 @Column
 private String name;

 @ManyToOne(optional = true)
 @JoinColumn(name = "a_id", referencedColumnName = "id")
 private A parent;

 ...
}

看起来我必须为每个B分配适当的A。这解决了我的问题

a.getB().forEach(b -> b.setA(a));
我不知道这是不是一个好的解决办法?特别是因为我有其他属于
B

的实体找到了解决方案:

类中的方法
afterUnmarshal
BElement.java

@XmlType(propOrder = {"name", "children", })
@XmlRootElement(name = "a")
@XmlAccessorType( XmlAccessType.PROPERTY)
public class AElement implements Serializable {

 private String name;
 private List<BElement> children;

 @XmlElement(name = "metadatum")
 public List<BElement> getChildren(){
    return children;
 }

 ...
}
@XmlRootElement(name = "b")
@XmlType(propOrder = {"name"})
public class BElement implements Serializable{

 private String name;
 private AElement parent;

 ...
}
@Entity
public class A implements Serializable {


 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;

 @Column
 private String name;

 @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "parent")
 private List<B> children;

 public List<B> getChildren(){
    return children;
 }

 ...
}
public void afterUnmarshal(Unmarshaller u, Object parent) {
   this.a = (AElement)parent;
}

我认为您应该添加更多关于持久性的信息,这似乎是JPA的问题。您确定B表中存在列
a\u id
?无论如何,对于
@ManyToOne
optional=true
是不必要的,因为这是它的默认值,您也可以删除JoinColumn上的
referencedColumnName=“id”
。是的,有一个列id。我有一个用于插入数据的webclient,我正在尝试添加导出/导入功能。所以我认为问题与解封有关。是的,你说得对。。问题是解编。读取xml时,在对象B中没有将引用放在A中。要正确分配双向关系,必须在对象的两侧添加。简单地说,当你试图保持B的实例时,没有A的引用。更多信息:我正在通过DOZER进行映射。因此,映射类的每个字段的每个值都被映射到jpa类。之后,我在JPA类中得到了相同的值(也是所有的B条目)。然后,我调用我的persist函数。查看数据库,a_id列为空。这不是解决方法,但却是保持双向关系的正确方法。正如我在前面的评论中所说的。Dozer没有设置双方的关系。不管怎样,是否真的需要所有关系的双向性。。如果您将其移除(例如,B中的@ManyToOne),则所有操作都正常(没有上述解决方案)。是的,我需要双向操作。有没有一种方法可以使用DOZER映射双向?您的第一个问题是JAXB没有在B中设置引用。如果您采用这种方法,我认为您在尝试封送a时可能会遇到循环引用的问题。无论如何,请尝试使用
this
。这是什么意思?