2014-12-29 3 views
2

я использую весной 4.0.1, спящий режим 4.3.5, 1.9.2 Джексона и STS IDE Я создаю RESTful веб-сервис, который возвращает данные в формате JSON , когда я использую Hibernate генератор кода генерирует геттеры и сеттер связанных объектов, аннотированных @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") для источника и @ManyToOne(fetch = FetchType.LAZY) для ссылки , что вызывает бесконечную рекурсию при сериализации. Я попытался использовать аннотации @JsonIgnore и @JsonBackReference от Jackson, чтобы исправить эту проблему, но кажется, что они полностью игнорируются и бесконечная рекурсия все еще происходит.JsonIgnore и JsonBackReference игнорируются

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) 

Это мой объектные классы User.class

//i get that suggestion from some sites 
    @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" }) 
    @Entity 
    @Table(name = "user", catalog = "someSchema")  
    public class User implements java.io.Serializable { 

     private String name; 
     private String password; 
     private String username; 
     private Set<Telephone> telephones = new HashSet<Telephone>(0); 
     @JsonManagedReference 
     @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") 
     public Set<Telephone> getTelephones() { 
      return this.telephones; 
     } 

     public void setTelephones(Set<Telephone> telephones) { 
      this.telephones = telephones; 
     } 
    } 

Telephone.class

@Entity 
@Table(name = "telephone", catalog = "someSchema") 
public class Telephone implements java.io.Serializable { 


    private User user; 
    private String telephone; 

    @ManyToOne(fetch = FetchType.LAZY) 
//tried @JsonIgnore only and both 
    @JsonIgnore 
//tried @JsonBackReference only and both 
    @JsonBackReference 
    @JoinColumn(name = "user_id", nullable = false) 
    public User getUser() { 
     return this.user; 
    } 


    @JsonIgnore 
    @JsonBackReference 
    public void setUser(User user) { 
     this.user = user; 
    } 

} 

относительно регистрации Джексону моего приложения, я использовал XML конфигурации

<mvc:annotation-driven> 
     <mvc:message-converters> 
      <bean 
       class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
       <property name="objectMapper"> 
        <bean 
         class="web.jsonConverters.HibernateAwareObjectMapper" /> 
       </property> 
      </bean> 
     </mvc:message-converters> 
    </mvc:annotation-driven> 

и класс сопоставления

public class HibernateAwareObjectMapper extends ObjectMapper { 

    public HibernateAwareObjectMapper() { 
     Hibernate4Module hm = new Hibernate4Module(); 
     registerModule(hm); 
    } 
} 

У вас есть идеи, почему аннотации Jackson игнорируются?

любая помощь будет оценена ...

+0

возможно дубликат [@JsonIgnore и @JsonBackReference игнорируются] (http://stackoverflow.com/questions/16881382/jsonignore-and-jsonbackreference- игнорируются) –

+0

yup ..но ответов недостаточно, может ли кто-нибудь дать лучший ответ? –

+0

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

ответ

0

я нашел путь, аннотирования сеттера по @Transient

idont знаю почему, но это работает отлично

User.class

//i get that suggestion from some sites 
    @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" }) 
    @Entity 
    @Table(name = "user", catalog = "someSchema")  
    public class User implements java.io.Serializable { 

     private String name; 
     private String password; 
     private String username; 
     private Set<Telephone> telephones = new HashSet<Telephone>(0); 

     @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") 
     public Set<Telephone> getTelephones() { 
      return this.telephones; 
     } 

     public void setTelephones(Set<Telephone> telephones) { 
      this.telephones = telephones; 
     } 
    } 

Телефон.класс

@Entity 
    @Table(name = "telephone", catalog = "someSchema") 
    public class Telephone implements java.io.Serializable { 


    private User user; 
    private String telephone; 

    @ManyToOne(fetch = FetchType.LAZY) 

    @JoinColumn(name = "user_id", nullable = false) 
    public User getUser() { 
     return this.user; 
    } 

    @Transient 
    public void setUser(User user) { 
    this.user = user; 
     } 

    } 

Другой Наивные Решение

Я решил его вручную в моем RESTful контроллер

петлей над множеством телефонов и установить пользователя обнулить

@RestController 
    @RequestMapping("/user") 
    public class UserController extends ParentController { 

     static final Logger logger = Logger.getLogger(UserController.class.getName()); 
     @Autowired 
     IUserDao iuserdao; 

      @RequestMapping(value = "/signin", method = RequestMethod.POST) 
      public ResponseEntity<User> signin(@RequestBody LoginWrapper login) { 
       System.out.println("==============GET USER=============="); 
       try { 
        User user = iuserdao.signin(login); 
        if (user == null) { 
         HttpHeaders httpHeaders = new HttpHeaders(); 
         httpHeaders.set(ERR_HEADER_NAME, "user not exist"); 
         return new ResponseEntity<User>(httpHeaders, HttpStatus.NOT_FOUND); 
        } else { 
         List<Telephone> tels=user.getTelephones(); 
         for (Telephone telephone : tels) { 
          telephone.setUser(null); 
         } 
         return new ResponseEntity<User>(user, HttpStatus.OK); 
        } 

       } catch (Exception e) { 
        System.out.println(e.getMessage()); 
        return null; 
       } 

      } 

еще нужно лучший ответ о проблеме Джексона.

+1

Временная аннотация «работает», делая ее переходной к JPA - JPA не будет сохраняться или читать ее в/из базы данных в любом случае. Вы не можете смешивать и сопоставлять аннотации по полям и свойствам; все они должны быть одного типа (все поле или все свойства) и все на тех же типах методов, где вы заметили бы, что переходный процесс немедленно конфликтует с аннотацией ManyToOne. У вас может быть похожая ситуация с Джексоном, так что она только просматривает аннотации в ваших полях, игнорируя поля, установленные для методов доступа. – Chris

+0

Итак, чтобы сделать аннотации к джейсону, я должен сделать все свои аннотации по полям, не использующим методы доступа. ??? –

0

использование

import com.fasterxml.jackson.annotation.JsonBackReference; 

вместо

import org.codehaus.jackson.annotate.JsonBackReference; 
Смежные вопросы