JsonIgnore和JsonBackReference被忽略了

时间:2014-12-29 12:00:00

标签: json jackson

我正在使用spring 4.0.1,hibernate 4.3.5,jackson 1.9.2和STS IDE 我正在创建一个RESTful Web服务,它以JSON格式返回数据 当我使用Hibernate代码生成器时,它会为@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")生成由@ManyToOne(fetch = FetchType.LAZY)注释的关联实体的getter和setter 和Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) 作为参考 这会在序列化期间导致无限递归。我尝试使用Jackson的@JsonIgnore和@JsonBackReference注释来解决这个问题,但似乎它们被完全忽略了,无限递归仍在发生。

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

这是我的实体课程 User.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;
    }

}

Telephone.class

   <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>

关于将jackson注册到我的应用程序,我使用了xml config

public class HibernateAwareObjectMapper extends ObjectMapper {

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

和mapper类

{{1}}

你知道杰克逊注释被忽略的原因吗?

任何帮助将不胜感激......

2 个答案:

答案 0 :(得分:0)

我通过@Transient

注释了setter找到了一种方法

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

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)

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

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

    }

  

另一种天真的解决方案

我在RESTful Controller中手动解决了它

循环通过电话机并将用户设置为空

    @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 :(得分:0)

使用

import com.fasterxml.jackson.annotation.JsonBackReference;

而不是

import org.codehaus.jackson.annotate.JsonBackReference;