Reputation: 618
I have the class book:
@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
......................
}
Then, I have class Reservation
@Entity
@Table(name = "reservations")
@XmlRootElement
public class Reservation {
private String username;
private String isbn;
@Temporal(TemporalType.DATE)
private Date date;
@ManyToOne
@JoinColumn(name = "isbn")
private Book reservedBook;
@ManyToOne
@JoinColumn(name = "username")
private User userWhoReserved;
//Getters and setters
...........
}
In the resource class I try to get a specific book like this:
@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;
}
}
Now, it doesn't serialize field List bookReservations. I've tried a lot of ideas found on the internet, like annotating the getter for the list with @XmlElement or using other annotations in other places (I don't remember them now), but nothing worked.
EDIT: This is how a response looks like:
<book isbn="3333333333">
<title>Mere Christianity</title>
<authors>C. S. Lewis</authors>
<year>2000</year>
</book>
but I also want to show the reservations.
What seems to be the solution? Thanks! Sorin
Upvotes: 3
Views: 1240
Reputation: 618
Solved! But the problem was not the serializing, but the fact that method find() called by the EntityManager could not extract the reservations and put them into my book object, so the list remained empty and its corresponding element was not displayed. So, instead of using find(), it seems that one should use 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
}
Also, the @XmlAccessorType(XmlAccessType.FIELD) must be deleted from the Book class and the getter for the list should be annotated with @XmlElementWrapper(name = "reservations") and @XmlElement(name = "reservation").
Upvotes: 0
Reputation: 21978
Wrap with an @XmlRootelement
with nillable="true"
then an empty <reservations>
will be there.
@XmlElement
@XmlElementWrapper(nillable=true)
private List<Reservation> bookReservations;
Upvotes: 0
Reputation: 2214
My wild guest is that it's the problem of lazy loading, you may adding fetch = FetchType.EAGER in OneToMany and ManyToOne annotations.
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
......................
}
And in Reservation class:
public class Reservation {
private String username;
private String isbn;
@Temporal(TemporalType.DATE)
private Date date;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "isbn")
private Book reservedBook;
@ManyToOne
@JoinColumn(name = "username")
private User userWhoReserved;
//Getters and setters
...........
}
Upvotes: 1
Reputation: 148977
Use @XmlAccessorType.PROPERTY
instead of FIELD
. The JPA impl may be lazy loading the list of reservations, this action will be triggered by accessing the property (get method).
For More Information
Upvotes: 0
Reputation: 41935
I think the problem may be with the list bookReservations
being 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;
}
}
I use this code everyday and works for me (Ignore other annotations that I have not provided).
I have faced problem in these cases but only found that due to the list being null for some reason it is not serialized. Try checking whether the list is being set by JAXB in the setter method by debugging at that method.
Upvotes: 3