当前位置: 首页 > 知识库问答 >
问题:

JsonIgnore 和 Json 反向引用被忽略

韦安怡
2023-03-14

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

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

这是我的实体类用户.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;
        }
    }

电话.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;
    }

}

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

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

你知道为什么杰克逊的注释被忽略了吗?

任何帮助都将不胜感激。。。

共有2个答案

蒯宏达
2023-03-14

我通过用< code>@Transient注释setter找到了一种方法

我不知道为什么,但它运行良好

用户.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;
        }
    }

电话.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控制器中手动解决了它。

通过在电话机集合上循环并将用户设置为空

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

            }

关于杰克逊的问题,还需要一个更好的答案…

杨骏
2023-03-14

使用

import com.fasterxml.jackson.annotation.JsonBackReference;

而不是

import org.codehaus.jackson.annotate.JsonBackReference;
 类似资料:
  • 我正在使用RestEasy、Jboss 7和EJB 3.1。我正在创建一个以JSON格式返回数据的RESTful Web服务。 问题是我在一个实体上有一个关系,这会在序列化期间导致无限递归。我尝试使用Jackson的和annotation来解决这个问题,但似乎它们被完全忽略了,无限递归仍在发生。 这是我的用户类: 这是我角色课的一部分: 我在某处读到过,我应该用我的应用程序注册Jackson,以便

  • 问题内容: 但是,当我删除WHERE时,查询会停止使用该键(即使我明确地强制使用该键也是如此) 有什么解决方法吗? 我意识到我在第二个示例中选择了整个表,但是为什么mysql突然决定它还是要忽略我的FORCE而不使用键?没有密钥,查询大约需要10分钟。 问题答案: FORCE有点用词不当。这是MySQL文档所说的(重点是我的): 您还可以使用FORCE INDEX,其作用与USE INDEX(in

  • 我有一个shell脚本(我们称之为 ),它以下列形式输出数据,但不将其保存到文件中: 我想在外壳脚本中使用这些值作为环境变量。我目前正在使用以下shell代码执行此操作: 这非常有用,除非< code>=右边的值包含空格。例如: 我在<code>product.sh</code>中尝试了两种不同的方法: < li >用引号将值括起来(< code > FOO = " split value " )

  • 问题内容: 您好,我正在阅读hibernate文档。 http://docs.jboss.org/hibernate/annotations/3.5/reference/zh/html/entity.html 使用@ManyToMany批注在逻辑上定义了多对多关联。您还必须使用@JoinTable批注描述关联表和联接条件。如果关联是双向的,则一侧必须是所有者,而一侧必须是反向端(即,在更新关联表中

  • 本文向大家介绍Regular Expressions 反向引用和非捕获组,包括了Regular Expressions 反向引用和非捕获组的使用技巧和注意事项,需要的朋友参考一下 示例 由于对组进行了“编号”,因此某些引擎还支持匹配先前已再次匹配的组。 假设您想匹配长度等于3的两个等于字符串除以$您要使用的东西: 这将匹配以下任何字符串: 如果您希望引擎不为组编号,则可以声明其不捕捉。一个非捕获组

  • 问题内容: 有没有一种方法可以基于Cython扩展中嵌入的循环来中断()Python脚本? 我有以下python脚本: 这会运行一个循环,该循环是C ++ Cython扩展的一部分。然后,在按的同时,将引发,但将其忽略,并且程序将继续进行直到模拟结束。 我发现的解决方法是通过捕获信号来处理扩展中的异常: 然后 : 我不能通过Python或至少从Cython进行这项工作吗?当我要在Windows /