JSON使用hibernate jpa序列化和反序列化以在JSON响应中将父对象变为子对象 [英] JSON serializing and deserializing with hibernate jpa to have parent object into child in JSON response

查看:1091
本文介绍了JSON使用hibernate jpa序列化和反序列化以在JSON响应中将父对象变为子对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Spring框架,Hibernate和JSON开发其他Web应用程序。请假设我有两个实体,如下所示:

BaseEntity.java

  @MappedSuperclass 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =id)
公共抽象类BaseEntity实现Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
私人长ID;
public long getId(){
return id;
}
}

University.java

  public class University扩展BaseEntity {

private String uniName;

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,orphanRemoval = true)
@JoinColumn(name =university_id)
private List< Student> students = new ArrayList<>();
// setter a getter
}

Student.java

  public class Student扩展BaseEntity {

private String stuName;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =university_id,updatable = false,insertable = false)
私立大学;

// setter a getter
}

我的休息API列表大学的每一件事情都正常工作,但我打电话给我的休息api时急切地列出学生我的JSON响应是

 <$ c 
$b
id:1,
stuName:st1,
university:{
id:1,
uniName:uni1
}
},
{
id:2,
stuName:st2,
university:1
}
]

但我的< $ b

  [
{
id:1,
stutName:st1,
university:
{
id:1,
uniName:uni1
}
},
{
id:2,
stutName:st2,
university:
{
id:1,
uniName:uni 1

}

更新1 :我的hibernate注释工作正常我有JSON问题



要求:


  1. 我需要热切地接受双方的提取(大学方面没问题)


  2. 每个学生都需要学生方面的大学对象(当我热切地提取学生时)


什么样的序列化或JSON配置我需要这样做来匹配我想要的响应?



更新2:如下所示:
$ b


  @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(名称=university_id,updatable = false,可插入= false)
@JsonIgnoreProperties(value =students,allowSetters = true)
私立大学;


json响应仍然相同
我需要我的< 所需的响应是上面提到的。



谢谢

解决方案

我有同样的问题。休眠(或eclipselink)不是问题。
JPA中唯一的约束是FetchType.EAGER



在BaseEntity中,我添加了一个标准方法

  public String getLabel(){
returnid:+ this.getId();
}

这种方法很抽象,但我有很多课, '

在父实体中,在这种情况下,大学,重写方法

  @Override 
public String getLabel {
return this.uniName;

$ / code>

对于每个父类,使用一个特定的字段作为实体的标签



定义MyStandardSerializer:

  public class StandardJsonSerializer扩展JsonSerializer< EntityInterface> {
$ b @Override
public void serializeWithType(EntityInterface value,JsonGenerator jgen,SerializerProvider provider,TypeSerializer typeSer)throws IOException,JsonProcessingException {
serialize(value,jgen,provider);

$ b @Override
public void serialize(EntityInterface value,JsonGenerator jgen,SerializerProvider provider)
抛出IOException,JsonProcessingException {
jgen.writeStartObject() ;
jgen.writeNumberField(id,(long)value.getId());
jgen.writeStringField(label,value.getLabel());
jgen.writeEndObject();
}

}

在学生类中,在univrsity上添加:

$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @ $ @Coin(name =university_id,updatable = false,insertable = false)
@JsonSerialize(使用= StandardJsonSerializer.class)
私立大学;

现在您已经解决了循环。
当您需要标签时,请覆盖父实体中的方法。
当您需要某些特定字段时,请创建一个特定的序列化程序。


I am developing rest web app with spring framework, Hibernate and JSON. Please Assume that I have two entities like below:

BaseEntity.java

@MappedSuperclass
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id" )
public abstract class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    public long getId() {
        return id;
    }
}

University.java

 public class University extends BaseEntity {

      private String uniName;

       @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER,orphanRemoval = true)
      @JoinColumn(name = "university_id")
        private List<Student> students=new ArrayList<>();
    // setter an getter
    }

Student.java

    public class Student extends BaseEntity{

        private String stuName;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "university_id",updatable = false,insertable = false)   
        private University university;

    // setter an getter
        }

when I call my rest api to list University every things work fine as I expect, but when I call my rest api to list student eagerly my JSON response is

[
   {
    "id": 1,
    "stuName": "st1",
    "university": {
        "id": 1,
        "uniName": "uni1"
                 }
    },
    {
        "id": 2,
        "stuName": "st2",
        "university": 1
    }
]

but my desired response is:

[
    {
        "id": 1,
        "stutName": "st1",
        "university": 
        {
         "id": 1,
        "uniName": "uni1"
        }
    },
    {
        "id": 2,
        "stutName": "st2",
        "university": 
        {
         "id": 1,
        "uniName": "uni1"
        }
    }

Update 1: my hibernate annotation working fine I have JSON issue

Requirements :

  1. I need both side fetch eagerly(the university side is Ok)

  2. I need university object in student side for every student(when I fetching student eagerly)

What kind of serialization or JSON config I need to do that for matching my desired response?

Update 2:

by removing @JsonIdentityInfo and editing student side like below:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "university_id",updatable = false,insertable = false)
@JsonIgnoreProperties(value = "students", allowSetters = true)
private University university;

the json response still same I need my desired response that is mentioned above.

thanks

解决方案

I had the same problem. Hibernate (or eclipselink) are not the problem. The only constraint in JPA is the FetchType.EAGER .

In the BaseEntity I have added a standard method

public String getLabel(){
   return "id:"+this.getId();
}

this method would be abstract, but I had a lot of class and i didn't want to change it all so I added a default value.

In parent entity, in this case University, override the method

@Override
public String getLabel{
    return this.uniName;
}

For each parent class, use a particular field as a label for your entity

Define a MyStandardSerializer:

public class StandardJsonSerializer extends JsonSerializer<EntityInterface> {

@Override
public void serializeWithType(EntityInterface value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException {
        serialize(value, jgen, provider); 
}

@Override
public void serialize(EntityInterface value, JsonGenerator jgen, SerializerProvider provider) 
  throws IOException, JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeNumberField("id", (long) value.getId());
    jgen.writeStringField("label", value.getLabel());
    jgen.writeEndObject();
}

}

In the student class, on univrsity add:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "university_id",updatable = false,insertable = false)   
@JsonSerialize(using=StandardJsonSerializer.class)
private University university;

Now you have resolved circularity. When you need a label, override the method in the parent entity. When you need some particular fields, create a specific Serializer.

这篇关于JSON使用hibernate jpa序列化和反序列化以在JSON响应中将父对象变为子对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆