@JsonIgnore и @JsonBackReference игнорируются

Я работаю с RestEasy, Jboss 7 и EJB 3.1. Я создаю веб-службу RESTful, которая возвращает данные в формате JSON.

Проблема в том, что у меня есть отношение @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;
}

Я где-то читал, что я должен зарегистрировать Джексона в своем приложении, чтобы иметь возможность использовать обычную аннотацию 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() устарел.

Пожалуйста:

  • Вы хоть представляете, почему аннотации Джексона игнорируются?
  • Как я могу использовать обычные XML-аннотации JAXB вместо аннотаций Джексона?
  • Что я могу использовать вместо JaxbAnnotationIntrospector()?

Ответ на любой из этих вопросов приветствуется, спасибо.

Обновление:

На данный момент я исключил resteasy-jackson-provider, используя jboss-deployment-structure.xml, и вместо этого использую Jettison. Я все еще хочу знать, как я могу использовать Джексона!


person Ghada    schedule 02.06.2013    source источник


Ответы (6)


Проблема здесь, похоже, связана с использованием Set<User> вместо List<User>. У меня была точно такая же проблема, и переход с Set<User> на List<User> исправил это, иначе я всегда получал ошибку Infinite recursion от Джексона. Я не знаю, действительно ли это ошибка в Джексоне или вам нужно предоставить какие-то другие аннотации и т. Д. При использовании Set.

person mvestola    schedule 27.12.2013

используйте import com.fasterxml.jackson.annotation.JsonBackReference; вместо import org.codehaus.jackson.annotate.JsonBackReference;.

Это было проблемой для меня.

person user104309    schedule 27.03.2015
comment
Это сработало для меня (после нескольких дней борьбы). Это было необходимо после обновления версии jackson. Спасибо пользователю 104309! - person Paul S; 10.04.2015
comment
Легко попасться - собирался против Jackson 1.9, но среда разработки уже обновлена ​​до Jackson 2+, которая ничего не знает о старых аннотациях. - person Mike Demenok; 02.02.2016
comment
Как ни странно, у меня сработало обратное, в моем собственном варианте этой проблемы. stackoverflow.com/questions/35346794/. Тем не менее, если бы я не увидел этот ответ, я бы никогда не подумал даже проверить импорт. СПАСИБО!!! - person swv; 12.02.2016

У меня была эта проблема, и я получил тот же код для работы, обновив версию библиотеки Джексона в моей сборке (pom.xml) с 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.

person Pedro Affonso    schedule 16.10.2014

Смотри, у меня есть что-то похожее на тебя, и у меня все отлично работает...

@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(){...

Я не знаю, изменит ли что-нибудь перемещение аннотации наверх, но это единственное, что я вижу...

Ваше здоровье,

person Gaston G    schedule 17.07.2013

У меня была аналогичная проблема, когда моя функция-получатель не была названа на основе имени поля, поэтому анализ json все еще выполнялся для получателя. Изменение имени получателя решило проблему.

person dev Joshi    schedule 11.09.2020

я использую 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);
    }
}
person Ahmed Adel    schedule 29.12.2014