Объектная рекурсия в Java при попытке двунаправленного отображения

У меня есть два класса, которые имеют двунаправленное отношение и имеют рекурсивную проблему структуры объекта из-за способа, которым это устанавливается.

Employer employer = new Employer(); 
employer.setName("sample1");

Employee empl = new Employee();

List<Employer> listOfEmployers = new ArrayList<Employer>();
listOfEmployers.add(employer); //i am assuming this part of code is causing recursion issue

 empl.setEmployers(listOfEmployers);
 employer.setEmployee(empl); //will have recursive object structure

Это вызывает проблему при преобразовании Java-объекта в JSON (org.codehaus.jackson.map.JsonMappingException: бесконечная рекурсия). Из-за этого Джексон не может обработать Java-объект в JSON.

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

И какова правильная объектная модель для формирования такого рода отображения между Работодателем и Сотрудником без получения этой проблемы рекурсии на уровне Java?

1 ответ

Решение

Если у вас есть два объекта, a а также bоба из которых имеют v член, который указывает на другого:

A a = new A();
B b = new B();
a.name = "a";
a.v = b;
b.name = "b"
b.v = a;

Ну, как вы собираетесь представлять это как JSON? Или как любой другой формат последовательных данных?

{
   "name": "a",
   "v": {
       "name": "b",
       "v": {
          "name": "a",
          "v": {
             "name": "b",
             "v": {
                "name": "a",
                "v": {
                   "name": "b",
                   "v": {
                      "name": "a",
                      "v": {
                         "name": "b",
                         "v": {

... навсегда

У JSON нет стандартного способа справиться с этим. Вы можете решить это, сделав ссылки косвенными, с помощью явного ключа:

{
    "key1": {
          "name": "a",
          "v_key" : "key2"
    },
    "key2": {
          "name": "b",
          "v_key": "key1"
    }
}

В Java это может быть достигнуто с помощью чего-то вроде:

Map<String,Object> map = new HashMap<String,Object>();
A a = new A();
a.name = "a";
map.add("a", a);

B b = new B();
b.name = "b";
map.add("b", b);

a.v_key = "b";
b.v_key = "a";

Вы не сказали нам, какую библиотеку JSON вы используете. Могут быть подходы для автоматической обработки циклических зависимостей с подходом, аналогичным описанному выше. Ищите слово "циклический" в его документации.

(Для Джексона, см.: Бесконечная рекурсия с Джексоном JSON и Hibernate JPA)

Другие вопросы по тегам