Теперь вы решили круглость. Когда вам нужна метка, переопределите метод в родительской сущности. Когда вам нужны определенные поля, создайте определенный сериализатор.

имаюсь разработкой веб-приложения для отдыха с использованием Spring Framework, Hibernate и JSON. Пожалуйста, предположим, что у меня есть две сущности, как показано ниже:

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
        }

когда я вызываю api rest, чтобы перечислить University, все работает нормально, как я ожидаю, но когда я вызываю api rest, чтобы с нетерпением перечислять студента, мой ответ JSON

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

но мойжелательно ответ:

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

Обновление 1: моя спящая аннотация работает нормально, у меня проблема с JSON

Требования :

Мне нужно с обеих сторон получить с нетерпением (университетская сторона в порядке)

Мне нужен университетский объект на стороне студента для каждого студента (когда я с нетерпением выбираю студента)

Какой сериализации или конфигурации JSON мне нужно сделать, чтобы соответствовать желаемому ответу?

Обновление 2:

удалив@JsonIdentityInfo и редактирование студенческой стороны, как показано ниже:

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

ответ JSON по-прежнему такой же, мне нужен мойжелательно ответ, который упомянут выше.

Спасибо

 Hema11 окт. 2017 г., 15:04
да для того же я предоставил код .. Вы получите университет в студента
 Amit K Bist16 окт. 2017 г., 19:11
Можете ли вы проверитьstackoverflow.com/a/22617567/3530898
 Generic11 окт. 2017 г., 14:59
@ Хема мне нужно, чтобы в студенческой стороне был объект университета, а не идентификатор университета
 Hema11 окт. 2017 г., 14:56
Добавлять@JsonIgnore и попробовать
 varren15 окт. 2017 г., 15:11
@ Generic Не думайте, что это можно сделать простым общим способом. И ты думаешь, чтоlist University is Ok потому что у вас там нет дубликатов.@JsonIdentityInfo Механизм идентификатора / ссылки работает таким образом, что экземпляр объекта только полностью сериализуется один раз и на него ссылается идентификатор в другом местеgithub.com/FasterXML/jackson-databind/issues/372

Ответы на вопрос(8)

Единственное ограничение в JPA - это FetchType.EAGER. .

В BaseEntity я добавил стандартный метод

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

этот метод был бы абстрактным, но у меня было много классов, и я не хотел менять все это, поэтому я добавил значение по умолчанию.

В родительском объекте, в данном случае University, переопределите метод

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

Для каждого родительского класса используйте определенное поле в качестве метки для вашей сущности

Определите 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();
}

}

В студенческом классе по университету добавьте:

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

Теперь вы решили круглость. Когда вам нужна метка, переопределите метод в родительской сущности. Когда вам нужны определенные поля, создайте определенный сериализатор.

как вы отображаете ваши отношения, даже если они «работают нормально», не соответствует спецификации jpa для двунаправленных отношений. Видетьэтот вопрос и связанные ответы.

Подводя итог, можно сказать, что владельцем отношения является сторона «многие к одному», а сторона «один ко многим» снабжена пометкой mappedBy. Ваше картографическое решение, при котором отношения один-ко-многим владеют отношениями, обычно / не рекомендуется (как описано в ответах выше), но технически возможно. (Сторона @manyToOne пропускает некоторые атрибуты, такие как "updatable = false" в вашем примере)

Затем,с JPA и последней версией Hibernateполитика отложенной загрузки следующая:

 OneToMany: LAZY
 ManyToOne: EAGER
 ManyToMany: LAZY
 OneToOne: EAGER

Поэтому я бы предложил вам использовать эту политику отложенной загрузки по умолчанию и сменить владельца ваших отношений manyToOne, так как не кажется хорошей идеей собрать всех студентов с помощью одного запроса ресурса университета. (Вы слышали о нумерации страниц?)

Делая это, а также исключая коллекцию студентов из Marshalling, используя, например,@JsonIgnore, должен сделать свое дело.

 Generic20 окт. 2017 г., 10:19
и в этом случае требуется @JsonManagedReference, и я должен потерять некоторую функциональность, например, у меня не может быть объекта University на стороне студента в ответе Json.
 Rémi Bantos21 окт. 2017 г., 22:03
Я подробно изложил свой ответ. Вам действительно следует подумать об изменении способа отображения ваших отношений ManyToOne-OneToMany с соответствующими исключениями Marshalling для студентов, как описано здесь. Потому что то, как вы наносите на карту, и то, как Джексон выполняет сортировку, взаимосвязано. Также я понимаю, что вы хотите включить студентов с нетерпеливым типом извлечения, и я действительно советую вам не делать этого. Вместо этого вы должны предпочесть нумерацию страниц, например, чтобы получить их все.
 Generic20 окт. 2017 г., 10:14
Уважаемый @ Rémi Bantos Я попробовал bean с этой аннотацией, там работают без json, но они не работают с json. Если вы попытаетесь добавить связь университета с данными ученика, он не сможет добавить имя_университета в таблицу ученика.

Университет

public class University {

@Fetch(value = FetchMode.SELECT)
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "university_id")
@JsonIgnore 
 private List<Student> students;

}

Ученик

public class Student{
@ManyToOne
@JoinColumn(name = "university_id", insertable = true, updatable = true, nullable = true)
private University university;
}
 Hema11 окт. 2017 г., 15:12
Если вы правильно получаете формат первого объекта, то отображение работает нормально
 Generic11 окт. 2017 г., 15:09
это добавляет Uni ID вместо Uni объекта для второго студента
 Generic11 окт. 2017 г., 15:11
да, но как насчет другой части?
 Generic11 окт. 2017 г., 15:08
Я пытался. он вернул [{"id": 1, "stutName": "st1", "University": {"id": 1, "uniName": "uni1"}}, {"id": 2, "stutName": "st2", "университет": 1}]
 Hema11 окт. 2017 г., 15:10
первый объект вы получаете нужный формат правильно ...?

University.students в вашем JSON.

Удалить@JsonIdentityInfo

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

Добавлять@JsonIgnore студентам, чтобы избежать круга

public class University extends BaseEntity {

    private String uniName;

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

Если тебе нужноUniversity.students быть сериализованным в других контекстах,http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion читать. Другие варианты работы с двунаправленными отношениями описаны здесь.

 Chris20 окт. 2017 г., 18:30
Что вы пытаетесь сериализовать? Список <Студент> (тогда мой ответ должен работать) или университет?
 Generic20 окт. 2017 г., 09:44
При добавлении @JsonIgnore объект ученика будет игнорироваться в выводе json

@JsonIdentityInfo из базового класса, это приводит к тому, что университетский объект сериализует только идентификатор.

 Sachin Gupta11 окт. 2017 г., 11:45
Я думаю, что пользовательский сериализатор сделает работу
 Generic11 окт. 2017 г., 11:03
Мне нужно иметь @JsonIdentityInfo для удаления циклического исключения
 Generic11 окт. 2017 г., 11:52
в моем приложении есть тонны объекта, как это возможно! Мне нужно написать сериализатор для каждого?

@JsonRawValue в качестве аннотации для вашегоuniversity свойство. Поведение, с которым вы сталкиваетесь, происходит из-за коллапса ссылок - так какUniversity дважды, сериализатор пытается быть умным и просто возвращает ссылку во второй раз, когда он встречается.

РЕДАКТИРОВАТЬ:toString():

@Override
public String toString() {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(this);
}
 Generic21 окт. 2017 г., 09:12
после добавления @JsonRawValue ответ в формате строки будет [{"id": 1, "stuName": "stu1", "university": [email protected]}, {"id": 2, "stuName": "stu2 "," университет ": [email protected]}]
 Piotr Wilkin21 окт. 2017 г., 13:50
ДобавилtoString().
 Piotr Wilkin21 окт. 2017 г., 13:34
OverridetoString() дляUniversity класс с использованиемObjectMapper это возвращаетmapperObject.writeValueAsString(this) - это должно заставить его возвращать JSON, а не стандартtoString() представление.
 Generic21 окт. 2017 г., 09:30
так что будет дальше?
 Generic21 окт. 2017 г., 13:40
пожалуйста, можете ли вы предоставить код в своем ответе!

Можете ли вы также добавить @JoinColumn в сущность Student

@ManyToOne(fetch = FetchType.EAGER)  
@JoinColumn(name = student_id")

Также проверьте внешний ключ класса вашего юридического лица. Внешний ключ должен быть от другого юридического лица, верно? @JoinColumn (name = "university_id", foreignKey = @ForeignKey (name = "student_id")) ??

В противном случае вы также можете использовать «mappedBy».

@JoinColumn(name = "university_id", mappedBy="university")
        private List<Student> students=new ArrayList<>();
 Generic11 окт. 2017 г., 11:35
У меня проблема в JSON Out положить
 user323563811 окт. 2017 г., 11:34
это изменение влияет на выход Джейсона в вашей идее?

Добавьте @jsonignore для метода получения
и добавьте @jsonProperty в поле, как

@JsonProperty(access = Access.READ_ONLY)
private String password;

Недавно к Джексону добавили некоторые функции, такие как Readonly и writeonly
Вы можете сослаться на это:
http://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonProperty.Access.html

 Generic20 окт. 2017 г., 15:36
результат один и тот же без каких-либо различий
 vishal paalakurthi20 окт. 2017 г., 15:22
на стороне студента добавьте жанр, такой как @JsonProperty (access = Access.READ_ONLY) частного университетского университета;
 Generic20 окт. 2017 г., 15:17
где я могу добавить @JsonProperty (access = Access.READ_ONLY)? в университете сеттер!

Ваш ответ на вопрос