2013-08-13 18 views
8

Używam klas opartych na JPF i serwerach GlassFish 4.0, które chcę dostarczyć za pośrednictwem JAX-RS. To działa dobrze do tej pory dla prostych podmiotów. Jeśli jednak mam relację @OneToMany na przykład ORAZ istnieje połączona jednostka, serwer zwraca błąd wewnętrzny serwera 500. W takim przypadku nic nie jest rejestrowane w dzienniku serwera. Aby znaleźć błąd, utworzyłem małą niestandardową stronę JSP, aby uzyskać więcej informacji o tym, co się stało. Kod jest właśnie to:GlassFish 4.0 w/Jersey zwraca 500 błędów wewnętrznego serwera bez wyjątku

Status: <%= pageContext.getErrorData().getStatusCode() %> 
Throwable: <%= pageContext.getErrorData().getThrowable() %> 

Niestety, wyjście jest tylko „Status: 500 Throwable: null”

Mój własny serwer jednostronny kodu wydaje się działać prawidłowo (czy jakiś wyjście debugowania), ale jednak , pojawia się błąd. W tym przykładzie Klasy użytkowników i problem może być pobierane bez problemu chyba nie jest powiązany podmiot IssueComment:

klasa użytkownika:

package my.application.model; 

import static javax.persistence.FetchType.LAZY; 

import java.io.Serializable; 
import java.util.List; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.xml.bind.annotation.XmlRootElement; 

/** 
* The persistent class for the User database table. 
* 
*/ 
@XmlRootElement 
@Entity(name="User") 
@Table(name="User") 
public class User implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private int id; 

    @Column(name="failedLogin") 
    private short failedLogin; 

    @Column(name="firstname") 
    private String firstname; 

    @Column(name="lastname") 
    private String lastname; 

    @Column(name="middlename") 
    private String middlename; 

    @Column(name="password") 
    private String password; 

    @Column(name="username") 
    private String username; 

    //bi-directional many-to-one association to IssueComment 
    @OneToMany(mappedBy="user", fetch = LAZY) 
    private List<IssueComment> issueComments; 

    //bi-directional many-to-one association to SignalComment 
    @OneToMany(mappedBy="user", fetch = LAZY) 
    private List<SignalComment> signalComments; 

    //bi-directional many-to-one association to SignalMeasure 
    @OneToMany(mappedBy="user", fetch = LAZY) 
    private List<SignalMeasure> signalMeasures; 

    public User() { 
    } 

    public int getId() { 
     return this.id; 
    } 

     // more getters and setters auto-generated by Eclipse 
     } 

klasa użytkownika:

package my.application.model; 

import java.io.Serializable; 
import java.util.Date; 
import java.util.List; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 
import javax.xml.bind.annotation.XmlRootElement; 

@NamedQuery(
    name = "getSingleIssue", 
    query = "SELECT i FROM Issue i WHERE i.id = :id" 
) 
/** 
* The persistent class for the Issue database table. 
* 
*/ 
@XmlRootElement 
@Entity(name="Issue") 
@Table(name="Issue") 
public class Issue implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name="id") 
    private int id; 

    @Column(name="concernedModule") 
    private String concernedModule; 

    @Column(name="createdate") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date createdate; 

    @Column(name="duedate") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date duedate; 

    @Column(name="priority") 
    private int priority; 

    @Column(name="reminderdate") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date reminderdate; 

    @Column(name="responsibleUserId") 
    private int responsibleUserId; 

    @Column(name="sendingModule") 
    private String sendingModule; 

    @Column(name="severity") 
    private int severity; 

    @Column(name="status") 
    private int status; 

    @Column(name="title") 
    private String title; 

    // bidirectional many-to-one association to IssueComment 
    @OneToMany(mappedBy = "issue") 
    private List<IssueComment> issueComments; 

    public Issue() { 
    } 

    public int getId() { 
     return this.id; 
    } 

// more getters and setters.... 
} 

IssueComment:

package my.application.model; 

import java.io.Serializable; 

import javax.persistence.*; 

import java.util.Date; 


/** 
* The persistent class for the IssueComment database table. 
* 
*/ 
@Entity(name="IssueComment") 
@Table(name="IssueComment") 
public class IssueComment implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    @Column(name="id") 
    private int id; 

    @Lob 
    @Column(name="comment") 
    private String comment; 

    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name="time") 
    private Date time; 

    //bi-directional many-to-one association to Issue 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name="issueId") 
    private Issue issue; 

    //bi-directional many-to-one association to User 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name="userId") 
    private User user; 

    public IssueComment() { 
    } 

    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

// getters/setters.... 
} 

Usługa internetowa wygląda następująco:

package my.application.server.webservice; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.QueryParam; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.ext.Provider; 

import org.glassfish.jersey.server.ResourceConfig; 

import my.application.data.UserStorage; 
import my.application.logger.Logger; 
import my.application.model.Signal; 
import my.application.model.SignalComment; 
import my.application.model.User; 

@Provider 
@Path("User") 
public class UserService extends ResourceConfig { 

    private UserStorage storage = new UserStorage(); 

    public UserService() { 
     this.packages("my.application.model"); 
    } 

    @Produces(MediaType.APPLICATION_XML) 
    @Path("load") 
    @GET 
    public User getUser(@QueryParam("id") int id) { 
     try { 
      Logger.getInstance().log("fetching id: " + id); 
      User u = storage.getUser(id); 
      Logger.getInstance().log("number of signal comments: " + u.getSignalComments().size()); 
      SignalComment sc = u.getSignalComments().get(0); 
      Logger.getInstance().log("Signal 0 comment: " + sc.getComment()); 
      Signal s = sc.getSignal(); 
      Logger.getInstance().log("Signal subject: " + s.getSubject()); 
      return u; 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     // this code is not being reached (so no errors in this method): 
     Logger.getInstance().log("---EXCEPTION HAS BEEN THROWN---"); 

     return null; 
    } 
} 

Zostawiłem kod źródłowy klienta, ponieważ jest on jednostronny i można go odtworzyć za pomocą zwykłej przeglądarki, więc nie ma potrzeby wprowadzania tutaj kodu klienta. IMHO.

+0

Wygląda jak wyjątek wskaźnika pustego. Czy możesz debugować? –

+0

Czy w swoim pliku web.xml jest włączony tryb programowania? – unwichtich

+0

@Sotirios: Niestety nie - kiedy próbuję ustawić rejestrowanie na FINEST lub uruchomić serwer w trybie debugowania, Eclipse otrzymuje wyjątek TimeOutException podczas próby uruchomienia GlassFish. Wypróbuję tryb programowania. Obecnie nie jest włączony. – grobmotoriker

Odpowiedz

8

Upewnij się, że nie ma żadnych cyklicznych odniesień na wykresie (obiektach), które próbujesz przenieść do formatu XML. Na przykład, może to powodować problem:

User -> IssueComment -> (the same) User 

lub

User -> IssueComment -> Issue -> IssueComment -> (the same) User 

Takie struktury nie może zostać zgromadzona w XML.

Uwaga: Dodaj @XmlRootElement adnotacji do IssueComment (myślę, że to nie jest potrzebne, ale lepiej mieć go tam).

Uwaga: Wiemy o problemie z logowaniem i zostanie on rozwiązany w ramach JERSEY-2000.

+0

Ah, dzięki! Sprawdzę to jutro! – grobmotoriker

+2

To wszystko! Bardzo dziękuję za informacje, także za informacje o problemie z logowaniem. Zanotowałem atrybuty (dla tego przykładu, atrybut użytkownika i wydania w IssueComment) z @XmlTransient, aby nie były brane pod uwagę przy zestawianiu obiektu. – grobmotoriker

+3

Dodatkowe informacje: jeśli doświadczasz tego problemu - nie atrybutów, ale metody getter powinny być opatrzone adnotacją @XmlTransient – grobmotoriker

Powiązane problemy