10

我正在使用 RestEasy、Jboss 7 和 EJB 3.1。我正在创建一个以 JSON 格式返回数据的 RESTful Web 服务。

问题是我@ManyToOne与我的一个实体有关系,这会在序列化过程中导致无限递归。我尝试使用杰克逊@JsonIgnore@JsonBackReference注释来解决问题,但似乎它们被完全忽略并且无限递归仍在发生。

这是我的用户类:

class User {
    private String userId;
    private Role role;

    @Id
    @Column(name = "\"UserId\"", unique = true, nullable = false, length = 30)
    public String getUserId() {
        return this.UserId;
    }

    public void setUserId(String UserId) {
        this.UserId = UserId;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "\"RoleId\"", nullable = false)
    //I have tried @JsonIgnore without @JsonBackReference 
    @JsonIgnore
    //I have tried @JsonBackReference without @JsonIgnore 
    //Also I have tried @JsonBackReference and @JsonIgnore together
    @JsonBackReference("role-User")
    public Role getRole() {
        return this.role;
    }
}

这是我的角色类的一部分:

@JsonManagedReference("role-User")
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "role")
public Set<User> getUsers() {
    return this.users;
}

我在某处读到我应该在我的应用程序中注册 Jackson 以便能够使用常规 Jaxb 注释,所以我创建了一个类

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonContextResolver implements ContextResolver<ObjectMapper> {
    public JacksonContextResolver() {
        ObjectMapper mapper = new ObjectMapper();
        AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

        mapper.getDeserializationConfig().setAnnotationIntrospector(
                introspector);
        mapper.getSerializationConfig().setAnnotationIntrospector(introspector);
    }

    public ObjectMapper getContext(Class<?> objectType) {
        return objectMapper;
    }
}

上述问题已JaxbAnnotationIntrospector()被弃用。

请:

  • 你知道为什么杰克逊注释被忽略了吗?
  • 如何使用常规的 JAXB XML 注释而不是 Jackson 的?
  • 我可以用什么代替JaxbAnnotationIntrospector()

感谢您对任何这些问题的回答,谢谢。

更新:

现在我已经排除了resteasy-jackson-provider使用jboss-deployment-structure.xml,而是使用了 Jettison。我仍然想知道如何使用杰克逊!

4

6 回答 6

9

这里的问题似乎与使用Set<User>而不是List<User>. 我遇到了完全相同的问题并从更改Set<User>List<User>修复此问题,否则我总是Infinite recursion从杰克逊那里得到错误。我不知道这是否真的是杰克逊的一个错误,或者你在使用Set.

于 2013-12-27T12:15:53.083 回答
6

使用import com.fasterxml.jackson.annotation.JsonBackReference;而不是import org.codehaus.jackson.annotate.JsonBackReference;.

这对我来说是个问题。

于 2015-03-27T07:16:49.393 回答
3

我遇到了这个问题,并通过将我的构建(pom.xml)中的 Jackson 库版本从 1.8.x 更新到 1.9.13 来获得相同的代码。如果您使用的是 maven,请编辑您的 pom.xml 以包含:

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>

文档没有帮助,但似乎 1.8.x 版本不支持对 Sets 的反向引用。

于 2014-10-16T18:33:02.637 回答
2

看,我有一些和你相似的东西,对我来说工作得很好......

@JsonBackReference("promotion-travel")
@ManyToOne(cascade = CascadeType.ALL)
    @JoinTable(name="PROMOTION_TRAVEL_REL",
        joinColumns = @JoinColumn(name="TRAVEL_ID"),
        inverseJoinColumns = @JoinColumn(name="PROMOTION_ID")
)
public Promotion getPromotion(){...

这就是我在 Entity1 上的内容

@JsonManagedReference("promotion-travel")
@OneToMany(mappedBy="promotion")
public List<Travel> getTravelList(){...

我不知道将注释移到顶部是否会改变任何东西,但这是我唯一能看到的......

干杯,

于 2013-07-17T19:36:16.353 回答
2

我有一个类似的问题,我的 getter 函数没有根据字段名称命名,因此 getter 的 json 解析仍在进行。更改吸气剂名称解决了这个问题。

于 2020-09-11T06:09:01.307 回答
0

我正在使用 spring 4.0.1、hibernate 4.3.5、jackson 1.9.2 和 STS IDE

我有同样的例外,但通过@Transient 不知道为什么注释设置器来解决,但它工作正常

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

}

关于将杰克逊注册到我的应用程序,我使用了 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);
    }
}
于 2014-12-29T18:31:03.543 回答