JSON output of Entity with OneToOne Relationship

I try to make output of my Entity Flight, which have OneToOne relationship with my other Entity Airplane but I get empty result and Eclipse start throwing exceptions in gson. Also before I added this relation ship to the Flight class there was no problem with my JSON output. Any ideas what I have to change to make it work properly.

My Flight class :

@Entity
@NamedQueries({ @NamedQuery(name = "Flight.getAll", query = "SELECT f FROM Flight f"), })
@NamedQuery(name = "Flight.getByDestination", query = "SELECT f FROM Flight f WHERE f.destinationFrom=:destinationFrom AND f.destinationTo=:destinationTo")
public class Flight implements Serializable {

@Transient
private static final long serialVersionUID = 1L;

public Flight() {
    super();
}

public Flight(FlightDestination destinationFrom, FlightDestination destinationTo, Integer flightPrice, Date date,
        Airplane airplaneDetail) {
    super();
    this.destinationFrom = destinationFrom;
    this.destinationTo = destinationTo;
    this.flightPrice = flightPrice;
    this.date = date;
    this.airplaneDetail = airplaneDetail;
}

public Flight(FlightDestination destinationFrom, FlightDestination destinationTo, Integer flightPrice, Date date) {
    super();
    this.destinationFrom = destinationFrom;
    this.destinationTo = destinationTo;
    this.flightPrice = flightPrice;
    this.date = date;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Enumerated(EnumType.STRING)
private FlightDestination destinationFrom;

@Enumerated(EnumType.STRING)
private FlightDestination destinationTo;

private Integer flightPrice;

@Temporal(TemporalType.DATE)
private Date date;

@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
@JoinColumn(name = "airplane_fk")
private Airplane airplaneDetail;

@Override
public String toString() {
    return "Flight [id=" + id + ", destinationFrom=" + destinationFrom + ", destinationTo=" + destinationTo
            + ", flightPrice=" + flightPrice + ", date=" + date + ", airplaneDetail=" + airplaneDetail + "]";
}}

Airplane Entity:

@Entity

public class Airplane implements Serializable {

private static final long serialVersionUID = 1L;

public Airplane() {
    super();
}

public Airplane(String planeModel, Integer seatingCapacity) {
    super();
    this.planeModel = planeModel;
    this.seatingCapacity = seatingCapacity;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

private String planeModel;

private Integer seatingCapacity;

@OneToOne(mappedBy = "airplaneDetail")
private Flight flight;

@Override
public String toString() {
    return "Airplane [id=" + id + ", planeModel=" + planeModel + ", seatingCapacity=" + seatingCapacity
            + ", flight=" + flight + "]";
}}

My WebService :

@Path("/flights")
public class FlightsWebService {

@PersistenceContext(unitName = "airline")
private EntityManager em;

@EJB
private FlightService fs;

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Flight> getFlights() {

    List<Flight> fList = fs.getAllFlights();
    return fList;

}}

But the result I get is this, when I add OneToOne relationship :

[{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":{"airplaneDetail":{"flight":

This is the exception :

Caused by: com.owlike.genson.TransformationException: Could not serialize property 'flight' from class com.airline.models.Airplane
at com.owlike.genson.reflect.PropertyAccessor.couldNotSerialize(PropertyAccessor.java:48)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:31)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.BeanViewConverter.serialize(BeanViewConverter.java:92)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:29)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.BeanViewConverter.serialize(BeanViewConverter.java:92)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.convert.CircularClassReferenceConverterFactory$CircularConverter.serialize(CircularClassReferenceConverterFactory.java:30)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:29)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.BeanViewConverter.serialize(BeanViewConverter.java:92)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:29)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.BeanViewConverter.serialize(BeanViewConverter.java:92)

Answers


The problem is a circular dependency Flight -> Airplane -> Flight -> Airplane -> .... The serializer goes into an endless loop. You can recognize this in the output that is generated.

A solution would be to ignore one side of the relation, see here for options to do this. One way is with annotation.

@Entity

public class Airplane implements Serializable {
...
    @JsonIgnore
    @OneToOne(mappedBy = "airplaneDetail")
    private Flight flight;
...
}

This will produce a list of flights with airplanes, but the backreference to flight will be ignored.

[
  {
    "airplaneDetail":
      {
        "planeModel":"...",
        "seatingCapacity":"..."
//  NO  "flight":{...}
      },
    "destinationFrom":{},
    "destinationTo":{},
    ...
  },
]

The answer Maarten give to us was right, the only thing I have to change to make this work is that @JsonIngore works on getter method of the field.


Need Your Help

App crashes on i386, works on x86_64

objective-c cocoa xcode x86-64 i386

I tried switching architectures in my Xcode project today, because I was about to use low level QuickTime stuff that's not yet ported to 64 bit yet. When i compiled before on x86_64 my app ran just...