2013-08-13 29 views
8

Tôi đang sử dụng máy chủ GlassFish 4.0 và các lớp dựa trên JPA phía máy chủ, mà tôi muốn phân phối qua JAX-RS. Điều này hoạt động tốt cho đến nay cho các thực thể đơn giản. Tuy nhiên, nếu tôi có mối quan hệ @OneToMany chẳng hạn VÀ có một thực thể được liên kết, máy chủ trả về lỗi máy chủ nội bộ 500. Trong trường hợp đó, không có gì được ghi vào nhật ký máy chủ. Để tìm lỗi, tôi đã tạo một trang JSP tùy chỉnh nhỏ để có thêm thông tin về những gì đã xảy ra. Mã này chỉ này:GlassFish 4.0 w/Jersey trả về 500 lỗi máy chủ nội bộ mà không có ngoại lệ

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

Thật không may, sản lượng chỉ là "Tình trạng: 500 Throwable: null"

riêng máy chủ mặt Mã của tôi dường như để chạy đúng (đã làm một số debug đầu ra), nhưng tuy nhiên , một số lỗi xuất hiện. Trong ví dụ này, các lớp người dùng và phát hành có thể được lấy ra mà không có một vấn đề, trừ khi có một thực thể IssueComment liên kết:

tài lớp:

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 
     } 

tài lớp:

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.... 
} 

Dịch vụ web như sau:

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; 
    } 
} 

Tôi đã để lại mã nguồn khách hàng vì nó ở phía máy chủ và có thể được sao chép bằng trình duyệt thông thường, vì vậy không cần thiết phải có mã máy khách tại đây IMHO.

+0

Dường như ngoại lệ con trỏ null. Bạn có thể gỡ lỗi không? –

+0

Bạn đã bật chế độ Phát triển trong web.xml chưa? – unwichtich

+0

@Sotirios: Thật không may là không - khi tôi cố gắng đặt nhật ký thành FINEST hoặc để khởi động máy chủ trong chế độ gỡ lỗi, Eclipse sẽ nhận được một TimeOutException khi cố gắng khởi chạy GlassFish. Tôi sẽ thử chế độ phát triển. Nó hiện không được bật. – grobmotoriker

Trả lời

8

Đảm bảo bạn không có bất kỳ tham chiếu tuần hoàn nào trong đồ thị (đối tượng) mà bạn đang cố gắng sắp xếp theo XML. Ví dụ, điều này có thể gây ra một vấn đề:

User -> IssueComment -> (the same) User 

hoặc

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

cấu trúc như vậy không thể được marshalled vào XML.

Lưu ý: Thêm @XmlRootElement chú thích vào IssueComment (Tôi nghĩ điều này không cần thiết nhưng tốt hơn nên có ở đó).

Lưu ý: Chúng tôi biết về sự cố đăng nhập và sự cố sẽ được giải quyết như một phần của JERSEY-2000.

+0

Ah, cảm ơn! Tôi sẽ kiểm tra điều đó vào ngày mai! – grobmotoriker

+2

Đúng rồi! Cảm ơn rất nhiều về thông tin, cũng cho thông tin về vấn đề đăng nhập. Tôi đã chú thích các thuộc tính (cho ví dụ đó, thuộc tính người dùng và vấn đề trong sự cố nhận biết) với @XmlTransient để chúng không được tính đến khi marshalling đối tượng. – grobmotoriker

+3

Thông tin bổ sung: nếu một người đang gặp sự cố đó - không phải thuộc tính, nhưng các phương thức getter nên được chú thích bằng @XmlTransient – grobmotoriker

Các vấn đề liên quan