@JsonIgnore和@JsonBackReference被忽略了

时间:2013-06-02 09:16:51

标签: json jackson jboss7.x resteasy ejb-3.1

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

问题是我的一个实体上有一个@ManyToOne关系,导致序列化过程中无限递归。我尝试使用Jackson的@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。我仍然想知道如何使用杰克逊!

6 个答案:

答案 0 :(得分:5)

使用import com.fasterxml.jackson.annotation.JsonBackReference;代替import org.codehaus.jackson.annotate.JsonBackReference;

这对我来说是个问题。

答案 1 :(得分:4)

此处的问题似乎与使用Set<User>而非List<User>有关。我遇到了完全相同的问题,并且从Set<User>更改为List<User>修复此问题,否则我总是遇到杰克逊的Infinite recursion错误。我不知道这是不是杰克逊的错误,或者在使用Set时是否需要提供其他注释等。

答案 2 :(得分: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版本不支持集合的反向引用。

答案 3 :(得分: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(){...

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

干杯,

答案 4 :(得分:0)

我使用的是spring 4.0.1,hibernate 4.3.5,jackson 1.9.2和STS IDE

我有同样的例外,但通过@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;
        }
    }

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

}

关于将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>

和mapper类

public class HibernateAwareObjectMapper extends ObjectMapper {

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

答案 5 :(得分:0)

我有一个类似的问题,即我的getter函数未基于字段名称命名,因此json解析仍在为getter进行。更改吸气剂名称即可解决问题。