【问题标题】:Hibernate one-to-many to JSON gives : 500 internal server error休眠一对多到 JSON 给出:500 内部服务器错误
【发布时间】:2016-03-31 06:35:09
【问题描述】:

我有 2 个 POJO。

一个配置文件类,其中:id、name、messages(消息列表)映射为一对多关系。

具有 id、消息、配置文件的消息类(与 ManyToOne 映射)

个人资料类

@XmlRootElement
@Entity
@Table(name="Profile")
public class Profile {
    @Id
    @GeneratedValue
    @Column(name="profile_id")
    private int id;
    private String name;
    @OneToMany(mappedBy="profile")
    private List<Message> messages = new ArrayList<Message>();

消息类

@XmlRootElement
@Entity
@Table(name="Message")
public class Message {
    @Id
    @GeneratedValue
    private int id;
    private String message;
    @ManyToOne
    @JoinColumn(name="profile_id")
    private Profile profile;

发布方式

@POST
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public Profile test(){

    Profile profile = new Profile(1,"John");

    Message message = new Message("Hello World!");

    Session session = sessionFactory.openSession();
    session.beginTransaction();

    profile.getMessages().add(message);
    session.save(profile);

    message.setProfile(profile);
    session.save(message);

    session.getTransaction().commit();
    session.close();

    return profile;
}

当我在 Chrome 中通过 Postman 发出请求时,我收到“500 Internal Server Error”。

奇怪的是它在我的数据库中插入。它正确地完成了它(它使用外键将消息映射到配置文件),但它似乎无法将响应作为 Json 返回。

如果我不保存消息(使用 session.save(message),它会返回正确的响应,但不再映射它。

如何使用一对多关系获得 Json 响应?

【问题讨论】:

  • 第一步:检查您的服务器日志/控制台,并阅读错误堆栈跟踪。
  • 控制台没有错误。我只在 Postman 中看到 500 内部服务器错误
  • 你在 HTTP 响应中也没有错误吗?如果是这样,首先要做的是改进日志记录。看不到错误会阻止您进行任何分析。
  • 我刚刚看到邮递员也给了我这个:“格式错误的 JSON:意外'
  • 我会首先确保您可以返回一个简单的对象作为 JSON。排除你的 test() 产生错误的东西,或者你错误地使用 PostMan。然后重新添加关系并从那里进行调试。

标签: java json hibernate rest jersey


【解决方案1】:

我发现这些 500 Server 错误通常是由 JSON 编组过程中的电路引起的。

例如,Jersey 开始将您的 Profile 对象编组为 JSON。它执行 id、name,然后开始编组 messages 属性。

它将第一个 Message 对象从数组中取出并开始编组。第一个 Message 对象有一个 id、名称和对 Profile 对象的引用。此时,它跟随 Profile 对象并重新开始编组它。

您可以看到您进入了一个未终止的递归过程。最终停止递归编组的是您在堆栈耗尽时遇到的 500 服务器错误。

要阻止这种情况,您可以对对象进行自定义编组,也可以简单地将 @JsonIgnore 属性放在 Message 类的配置文件属性上。

如果您发现需要更多控制,请查看 com.fasterxml.jackson.databind.JsonSerializer。

【讨论】:

    【解决方案2】:

    我在这个问题上挠了整整一天。同样的行为,我也无法在控制台上看到任何日志。甚至 @jsonIgnoreproperties 也没有帮助我。

    所以我继续前进,在返回响应之前,我遍历了我的响应对象并将 null 值设置为子对象中的父参数。

    List<Message> messages=Profile.getMessage();
    
    for (Message msg:messages){
    msg.setProfile(null);
    }
    

    这对我有用,因为我的子对象中不需要父对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-01
      • 2014-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多