在JAX-RS中序列化java.util.list

在JAX-RS中序列化java.util.list,java,web-services,jpa,jaxb,jax-rs,Java,Web Services,Jpa,Jaxb,Jax Rs,我有一本教科书: @Entity @Table(name = "books") @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType public class Book { @Id @XmlAttribute private String isbn; private String title; private String authors; private int year

我有一本教科书:

@Entity
@Table(name = "books")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType

public class Book {
    @Id
    @XmlAttribute
    private String isbn;

    private String title;
    private String authors;
    private int year;

    @OneToMany(mappedBy="reservedBook")
    private List<Reservation> bookReservations;

    //Getters, setters, addReservation, remove Reservation
        ......................
}
在资源类中,我尝试获得一本具体的书,如下所示:

@GET
@Path("/{isbn}")
@Produces(MediaType.TEXT_XML)
public Book getBookByIsbn(@PathParam("isbn") String isbn) {

    Book book = entityManager.find(Book.class, isbn);

    if (book != null) {
        return book;

    }

}
现在,它不会序列化字段列表bookReservations。我尝试了很多在互联网上找到的想法,比如用@xmlement为列表注释getter,或者在其他地方使用其他注释(我现在不记得了),但是没有任何效果

编辑:这是响应的外观:

<book isbn="3333333333">
    <title>Mere Christianity</title>
    <authors>C. S. Lewis</authors>
    <year>2000</year>
</book>

返璞归真
刘易斯
2000
但我也想展示一下预订情况

解决办法似乎是什么? 谢谢
Sorin

我认为问题可能在于列表
bookReservations
null

class A{

    private List<String> someList = new ArrayList<String>();

    @XmlElement(name = "some-tag")
    public List<String> getList() {
        return someList;
    }

    public void setSomeList(List<String> someOtherList) {
        this.someList = someOtherList;
    }
}
A类{
private List someList=new ArrayList();
@xmlement(name=“some标记”)
公共列表getList(){
返回一些列表;
}
public void setSomeList(List someOtherList){
this.someList=someOtherList;
}
}
我每天都使用这段代码,并为我工作(忽略我没有提供的其他注释)


我在这些情况下遇到了问题,但只发现由于某种原因列表为空,所以它没有序列化。通过调试setter方法,尝试检查列表是否由JAXB在setter方法中设置。

使用
@xmlacessortype.PROPERTY
而不是
字段。JPA impl可能延迟加载保留列表,此操作将通过访问属性(get方法)触发

了解更多信息


    • 我的不速之客是,这是延迟加载的问题,您可以在OneToMany和ManyToOne注释中添加fetch=FetchType.EAGER

      public class Book {
          @Id
          @XmlAttribute
          private String isbn;
      
          private String title;
          private String authors;
          private int year;
      
          @OneToMany(mappedBy="reservedBook",fetch = FetchType.EAGER)
          private List<Reservation> bookReservations;
      
          //Getters, setters, addReservation, remove Reservation
              ......................
          }
      

      解决了!但问题不在于序列化,而是EntityManager调用的find()方法无法提取保留并将其放入my book对象,因此列表仍然为空,其相应的元素没有显示。因此,与其使用find(),不如使用Query:

      Query query = entityManager.createQuery("SELECT book FROM Book book WHERE book.isbn = :_isbn ");
      query.setParameter("_isbn", isbn);
      
      
      //if getSingleResult() doesn't find a book, an exception will be thrown
      try {
              Book book = (Book)query.getSingleResult();
              return book;
          }
          catch(RuntimeException e)
          {
              //do something
          }
      

      此外,必须从Book类中删除@XmlAccessorType(XmlAccessType.FIELD),列表的getter应该用@XmlElementWrapper(name=“reservations”)和@XmlElement(name=“reservations”)进行注释。

      @XmlRootelement
      nillable=“true”
      进行包装,然后将出现一个空的

      @XmlElement
      @XmlElementWrapper(nillable=true)
      private List<Reservation> bookReservations;
      
      @xmlement
      @XmlElementWrapper(nillable=true)
      私人列表预订;
      
      您是否尝试在OneToMany和ManyToOne批注中添加fetch=FetchType.EAGER?@Thinbk:我已经解决了问题…我发布了解决方案。是的,它为空,但由于EntityManager.find()方法无法获取它…但您通常使用EntityManager.find()或查询来获取结果吗?find()方法似乎没有提取保留并将它们放入my Book对象中……您必须配置
      @OneToMany(fetch=FetchType.EAGER,mappedBy=“reservedBook”)私有列表bookReservations我已经按照我发布为答案的方式完成了,现在它可以工作了…但是,如果我按照你说的那样做,它是否可以与entityManager.find()一起工作?是的,它应该可以工作,如果你不将它配置为“急切”,那么它就不会获取关系记录。
      
      Query query = entityManager.createQuery("SELECT book FROM Book book WHERE book.isbn = :_isbn ");
      query.setParameter("_isbn", isbn);
      
      
      //if getSingleResult() doesn't find a book, an exception will be thrown
      try {
              Book book = (Book)query.getSingleResult();
              return book;
          }
          catch(RuntimeException e)
          {
              //do something
          }
      
      @XmlElement
      @XmlElementWrapper(nillable=true)
      private List<Reservation> bookReservations;