2015-06-16 3 views
0

Я работаю над приложением Spring-MVC, в котором у меня есть 3 класса, GroupCanvas, GroupSection, GroupNotes. GroupCanvas имеет сопоставление «один ко многим» с GroupSection, а GroupSection имеет сопоставление «один ко многим» с GroupNotes. Я пытаюсь извлечь заметки на основе первичного ключа GroupCanvas, но я получаю исключение инициализации Hibernate Lazy. Я опробовал рекомендации по сети, в основном SO, но ни один из них, похоже, не помогает. Вот код.Spring MVC, Hibernate: Lazy exception exception

ДАО Метод ошибки метания:

@Override 
    public List<GroupNotes> searchNotesByDays(int days, int mcanvasid) { 
     Session session = this.sessionFactory.getCurrentSession(); 
     Calendar cal = Calendar.getInstance(); 
     cal.add(Calendar.DAY_OF_YEAR, -days); 
     long daysAgo = cal.getTimeInMillis(); 
     Timestamp nowMinusDaysAsTimestamp = new Timestamp(daysAgo); 
     Query query = session.createQuery("from GroupSection as n where n.currentcanvas.mcanvasid=:mcanvasid"); 
     query.setParameter("mcanvasid", mcanvasid); 
     List<GroupSection> sectionList = query.list(); 
     List<GroupNotes> notesList = new ArrayList<GroupNotes>(); 
     for (GroupSection e : sectionList) { 
      Query query1 = session.createQuery("from GroupNotes as n where n.ownednotes.msectionid=:msectionid and n.noteCreationTime >:limit"); 
      query1.setParameter("limit", nowMinusDaysAsTimestamp); 
      query1.setParameter("msectionid",e.getMsectionid()); 
      notesList.addAll(query1.list()); 
     } 
     return notesList; 
    } 

GroupCanvas Модель:

@Entity 
@Table(name = "membercanvas") 
public class GroupCanvas{ 

variables, getters, setters ignored 
    @OneToMany(mappedBy = "currentcanvas",fetch=FetchType.LAZY, cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<GroupSection> ownedsection = new HashSet<>(); 

    public Set<GroupSection> getOwnedsection() { 
     return this.ownedsection; 
    } 

    public void setOwnedsection(Set<GroupSection> ownedsection) { 
     this.ownedsection = ownedsection; 
    } 
} 

GroupSection модель класса:

@Entity 
@Table(name = "membersection") 
public class GroupSection { 
@ManyToOne 
    @JoinColumn(name = "groupcanvasid",nullable = false) 
    @JsonIgnore 
    private GroupCanvas currentcanvas; 

    public GroupCanvas getCurrentcanvas() { 
     return this.currentcanvas; 
    } 

    public void setCurrentcanvas(GroupCanvas currentcanvas) { 
     this.currentcanvas = currentcanvas; 
    } 

    public int getCurrentCanvasId(){ 
     return this.currentcanvas.getMcanvasid(); 
    } 


    @OneToMany(mappedBy = "ownednotes", fetch = FetchType.EAGER,cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<GroupNotes> sectionsnotes = new HashSet<>(); 

    public Set<GroupNotes> getSectionsnotes(){ 
     return this.sectionsnotes; 
    } 

    public void setSectionsnotes(Set<GroupNotes> sectionsnotes){ 
     this.sectionsnotes=sectionsnotes; 
    } 
} 

GroupNotes:

@Entity 
@Table(name="groupnotes") 
public class GroupNotes{ 
    @ManyToOne 
    @JoinColumn(name = "msectionid") 
    @JsonIgnore 
    private GroupSection ownednotes; 

    public GroupSection getOwnednotes(){return this.ownednotes;} 

    public void setOwnednotes(GroupSection ownednotes){this.ownednotes=ownednotes;} 
} 
Журнал

Ошибка:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.journaldev.spring.model.GroupCanvas.ownedsection, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownednotes"]->com.journaldev.spring.model.GroupSection["currentcanvas"]->com.journaldev.spring.model.GroupCanvas["ownedsection"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.journaldev.spring.model.GroupCanvas.ownedsection, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownednotes"]->com.journaldev.spring.model.GroupSection["currentcanvas"]->com.journaldev.spring.model.GroupCanvas["ownedsection"]) 
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:256) 

Что я делаю неправильно, любезно дайте мне знать. Если вам нужна дополнительная информация, прокомментируйте комментарий.

ответ

1

Конвертер JSON выполняется после завершения сеанса Hibernate. Конвертер JSON слепо обращается ко всем геттерам и сеттерам, даже к ленивым. Поэтому, когда Hibernate пытается инициализировать GroupCanvas # ownedSection, сеанса нет и, следовательно, это исключение вызывается.

Возможные решения:

  1. Не выполнять непосредственно JSON конвертер на Hibernate управляемые объекты. Создайте объекты DTO для выполнения этой задачи. Объекты DTO не имеют логики и являются чистыми java-компонентами и хорошо подходят для этой роли. Но недостатком является то, что вам нужно поддерживать еще одну иерархию классов. Преимущества перевешивают недостатки. Следующий пост может помочь с этим подходом:

    DTO pattern : Best way to copy properties between two Objects

  2. Используйте аннотации, чтобы отметить определенные поля, как не сериализации. Например, JsonIgnore. Недостатком этого является то, что если это поле когда-либо понадобится в другом API, вы не сможете его использовать.

  3. Если один из back-ref может быть исключен из вашей модели (примечания-> раздел/раздел-> холст), то это делает его «более дружественным» к сериализации. В других работах JSON не работает с циклическими ссылками, поэтому чем меньше количество двунаправленных/контурных конструкций, тем лучше. Если бы не возможность циклической ссылки, вы могли бы инициализировать все данные, необходимые для сериализации, включая GroupCanvas.

+0

Можете ли вы предложить мне, какие изменения мне нужно сделать в коде. Благодарю. –

+0

Кроме того, я не смогу устранить обратную ссылку, упомянутую в третьем решении. –

+0

Можете ли вы предоставить более подробную информацию о своем приложении? Где конверсия JSON? Какие технологии используются? Весна? Если да, покажите конфигурацию. – codedabbler