2014-09-07 4 views
24

Это является продолжение на следующий вопрос о JPA Transient аннотации Why does JPA have a @Transient annotation?JPA Transient аннотации и JSON

У меня есть переходный переменный, которую я не хочу, чтобы сохраняться и отмечаются с транзиторной аннотацией. Однако, когда я хочу создать JSON из моего контроллера останова, эта переходная переменная недоступна в выведенном JSON.

POJO PublicationVO прямолинейно без каких-либо причудливых атрибутов, только некоторые частные атрибуты (которые сохраняются) с геттерами и сеттерами и 1 переходная переменная.

@RequestMapping(value = { "{publicationId}"}, method = RequestMethod.GET, produces = "application/json") 
@ResponseBody public PublicationVO getPublicationDetailsJSON(@PathVariable(value = "publicationId") Integer publicationId) { 
    LOG.info("Entered getPublicationDetailsJSON - publicationId: " + publicationId); 

    //Call method to get the publicationVO based on publicationId 
    PublicationVO publicationVO = publicationServices.getPublicationByIdForRestCalls(publicationId);  
    LOG.info("publicationVO:{}", publicationVO); 

    LOG.info("Exiting getPublicationDetailsJSON"); 
    return publicationVO; 
} 

PublicationVO выглядит следующим образом

package com.trinity.domain.dao; 

import java.util.Calendar; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 
import javax.persistence.Transient; 

import com.fasterxml.jackson.annotation.JsonInclude; 

@Entity 
@Table(name = "publication") 
public class PublicationVO { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    private Integer id;  
    @Column(name = "publicationName", unique = false, nullable = false, length = 200) 
    private String publicationName; 
    @Column(name = "publicationSource", unique = false, nullable = false, length = 45) 
    private String publicationSource; 

    @Column(name = "dateAdded", unique = false, nullable = false) 
    private Calendar dateAdded; 

    @Transient 
    private float percentageProcessed; 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getPublicationName() { 
     return publicationName; 
    } 

    public void setPublicationName(String publicationName) { 
     this.publicationName = publicationName; 
    } 

    public String getPublicationSource() { 
     return publicationSource; 
    } 

    public void setPublicationSource(String publicationSource) { 
     this.publicationSource = publicationSource; 
    } 

    public Calendar getDateAdded() { 
     return dateAdded; 
    } 

    public void setDateAdded(Calendar dateAdded) { 
     this.dateAdded = dateAdded; 
    } 

    public float getPercentageProcessed() { 
     return percentageProcessed; 
    } 

    public void setPercentageProcessed(float percentageProcessed) { 
     this.percentageProcessed = percentageProcessed; 
    } 

    @Override 
    public String toString() { 
     return "PublicationVO [id=" + id + ", publicationName=" + publicationName + ", publicationSource=" + publicationSource + ", dateAdded=" + dateAdded 
       + ", percentageProcessed=" + percentageProcessed + "]"; 
    } 
} 

Когда я вижу заявление отладки для publicationVO в моих журналах, переходная переменная включается в выходные, но в моем клиентском коде, переходная переменная не включен в ответ json.

Любая помощь очень ценится.

Спасибо, Дэмиен

+0

Вы можете редактировать свой вопрос и опубликовать код PublicationVO? Имеет ли ваша переходная переменная не сериализация правильного геттера? – m4rtin

+0

@ m4rtin - я просто включил класс публикацииVo. И да переходная переменная имеет метод getter –

+0

Как я могу видеть аннотации Spring MVC, а также тег Spring в вашем вопросе, можете ли вы подтвердить, что сериализация JSON выполняется библиотекой Джексона? – m4rtin

ответ

23

Вопреки тому, что я говорил вам в комментариях, мне кажется, что Джексон действительно заботится о JPA аннотации, когда используется для сериализации экземпляров классов сущностей, благодаря Jackson's Hibernate module.

В этом модуле, есть HibernateAnnotationIntrospector, что документация относится как к

простого AnnotationIntrospector, который добавляет поддержку для использования переходных процессов в обозначают игнорируемые поля (наряду с Джексоном и/или JAXB аннотаций).

И как вы можете видеть here, поведение по умолчанию Джексона, чтобы проверить наличие @Transient аннотации можно найти.

Таким образом, в конце концов, ваша проблема может быть решена ни в одном из этих 3 способов:

  1. Настройка Джексон (с использованием setUseTransient метода HibernateAnnotationIntrospector), чтобы отключить проверку @Transient аннотаций (см this answer для деталей реализации).
  2. Использовать другой объект, кроме PublicationVO, в качестве возвращаемого результата вашего метода getPublicationDetailsJSON. Вам придется скопировать свойства из объекта значения в возвращаемый объект в какой-то момент.
  3. Удалите аннотацию @Transient и сохраняйте ее (но я бы понял, если это не вариант для вас, поскольку у вас, вероятно, есть веские основания для того, чтобы это свойство JPA-переходное в первую очередь).

Приветствие

+1

отличный ответ m4rtin. Я попробую шаг 1 утром, и если это не работает, я думаю, что шаг 2 может быть следующим логическим шагом –

+0

Большое спасибо за информацию m4rtin, она работает для нас. – Mohsin

+1

Выбор для Джексона, который даже заботится о аннотации спящего режима, находится вне меня. Эти ребята высоко или что-то в этом роде? –

16

Просто в дальнейшем добавить к ответу, предоставленного m4rtin

я пошел с первым подходом - Настройка Джексон (с использованием методы setUseTransient HibernateAnnotationIntrospector), чтобы отключить проверку @Transient аннотаций.

В моем проекте я follwed должен был следовать следующему потоку, чтобы избежать Джексона сериализации на не надуманных ленивых объектах Avoid Jackson serialization on non fetched lazy objects

Чтобы настроить мой проект, чтобы не игнорировать переходные аннотаций, я создал Hibernate4Module следующего

 Hibernate4Module hm = new Hibernate4Module(); 
    hm.disable(Feature.USE_TRANSIENT_ANNOTATION); 

Спасибо за вашу помощь в этом m4rtin

+0

Рад, что вы нашли детали реализации в отношении первого подхода, я отредактирую свой ответ, чтобы добавить ссылку на ваш ответ, который определенно будет полезен для людей, отправляющихся на решение 1. – m4rtin

28

Я просто добавил JsonSerialize и JsonDeserialize аннотаций.

@Transient 
@JsonSerialize 
@JsonDeserialize 
private String myField; 
+1

спасибо, это сработало для меня –

+0

Это не работает для меня вообще. –

+0

Это тоже не сработало. – Trevor

6

Я использую как @Transient, так и @JsonProperty, тогда он работает!

@Transient 
@JsonProperty 
private String mapImageSrc; 
+1

+1 Да, это тоже работает. JsonSerialize и JsonProperty, похоже, работают. Интересно, есть ли тонкие различия, и если один из них предпочтительнее другого. – HopeKing

+1

Вы можете даже уточнить доступ с помощью @JsonProperty (access = Access.WRITE_ONLY) или @JsonProperty (access = Access.READ_ONLY) – Selindek

0

использование @JsonIgnore в com.fasterxml.jackson.annotation там также @JsonFormat для переменной Date. работает для меня

0

Try @JsonView после добавления @Transient

+0

Использовать комментарии для тривиальных ответов и предложений –

0

Поскольку никакое другое решение здесь не работает для меня, позвольте мне опубликовать мое решение, как это сделал трюк для меня:

@Transient 
@JsonSerialize 
private String mapImageSrc; 

Это кажется чтобы быть лучшим решением для меня, поскольку в этом случае используется аннотация для @JsonSerialize.

-1

Что он работал на меня:

@Transient 
@JsonProperty 

в поглотителе (не в определении частного поля)

И

@JsonAutoDetect(fieldVisibility = Visibility.ANY) 

аннотирование класса

+0

Могу ли я спросить, почему downvoting? – fermat

Смежные вопросы