2016-03-03 62 views
0

我正在研究一個Spring-MVC應用程序,其中我試圖爲已存在的一對多映射之間添加多對多映射兩個實體。項目中有兩個實體,分別是GroupSectionGroupNotesSpring,Hibernate:用於多對多映射的惰性初始化異常

對於項目中的任務之一,我不得不介紹GroupSection和GroupNotes之間的多對多映射,但是我得到了一個懶惰的初始化異常。

錯誤:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: failed to lazily initialize a collection of role: com.tooltank.spring.model.GroupSection.groupSections, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.tooltank.spring.model.GroupSection["groupSections"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.tooltank.spring.model.GroupSection.groupSections, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.tooltank.spring.model.GroupSection["groupSections"]) 

這裏是控制器方法,其被稱爲:

@RequestMapping(value = "/sections/get/{canvasid}") 
    public @ResponseBody List<GroupSection> getAllSectionsForCanvas(@PathVariable("canvasid") int canvasid) { 
     boolean value = this.personService.getCanvasValuesForCanvas(canvasid); 
     return this.groupSectionService.listGroupSectionByCanvasid(canvasid, value); 
    } 

DAO方法(服務方法只是調用DAO法):

@Override 
    @Transactional(readOnly = true) 
    public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid) { 
     try { 
      Session session = this.sessionFactory.getCurrentSession(); 
      org.hibernate.Query query = session.createQuery("From GroupSection as msection where " + 
        "msection.currentcanvas.mcanvasid=:mcanvasid and msection.sectionDisabled=false and msection.sectionInActive=false"); 
      query.setParameter("mcanvasid", mcanvasid); 
      return query.list(); 
     }catch (Exception e){ 
      e.printStackTrace(); 
      return null; 
     } 
    } 

GroupSection模型:

import com.fasterxml.jackson.annotation.JsonIgnore; 
import org.hibernate.annotations.Type; 
import org.hibernate.annotations.TypeDef; 

import javax.persistence.*; 
import java.util.Date; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 
@Entity 
@Table(name = "membersection") 
public class GroupSection { 


// Below is self-mapping, required for one of the task, works. 
    @JsonIgnore 
    @ManyToOne 
    @JoinColumn(name = "owned_section_id", nullable = true) 
    private GroupSection primarySection; 

    @OneToMany(mappedBy = "primarySection", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) 
    private Set<GroupSection> groupSections = new HashSet<>(); 


// Many to many mapping, I had lazy loading before, but tried Eager to see if error goes, it doesn't. : 

    @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE) 
    @JoinTable(name = "sectionjunction",joinColumns = {@JoinColumn(name = "msectionid")}, 
      inverseJoinColumns = {@JoinColumn(name = "mnoteid")}) 
    private Set<GroupNotes> groupNotesSet = new HashSet<>(); 


// One to many mapping below : 

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

GroupNotes:

import com.fasterxml.jackson.annotation.JsonIgnore; 
import org.hibernate.annotations.Type; 
import org.hibernate.annotations.TypeDef; 

import javax.persistence.*; 
import java.util.Date; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 
@Entity 
@Table(name = "groupnotes") 
public class GroupNotes implements Serializable { 


    @JsonIgnore 
    @ManyToMany(mappedBy = "groupNotesSet",fetch = FetchType.EAGER) 
    private Set<GroupSection> groupSectionSet = new HashSet<>(); 

    @ManyToOne 
    @JoinColumn(name = "msectionid",nullable = true) 
    @JsonIgnore 
    private GroupSection ownednotes; 

// Self mappings : 


    @JsonIgnore 
    @ManyToOne 
    @JoinColumn(name = "owned_note_id", nullable = true) 
    private GroupNotes primaryNote; 

    @OneToMany(mappedBy = "primaryNote", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) 
    private Set<GroupNotes> groupNotesSet = new HashSet<>(); 
} 

我在做什麼錯?是否有可能同時在兩個類之間進行一對多和多對多映射?如果是的話,那麼該錯誤的處理是什麼。請讓我知道。謝謝。 :-)

+0

看起來問題出現在'private Set groupSections = new HashSet <>();'你能嘗試對這個對象進行Eager初始化嗎? –

+0

@BandiKishore:我嘗試過的第一件事,也嘗試過JSONIgnore,沒有幫助... –

+0

你可以嘗試https://github.com/FasterXML/jackson-datatype-hibernate它有助於與休眠和傑克遜的懶惰領域。 –

回答

0

當你調用listGroupSectionByCanvasid時,你打開一個事務和一個會話。當呼叫返回會話關閉時。當spring返回它試圖讀取你的對象的值,並且由於你的manytomany關係組的延遲加載groupNotesSet和groupSections是需要會話的hibernate集合。在你的情況下,會議不再存在。

+0

是的,因爲我已經嘗試了Eager初始化和/或JSONIgnore,沒有任何幫助。 –

+0

爲groupSections相同。在你的代碼中沒有渴望GroupSection – JEY

+0

是的,在多對多映射的雙方都急切加載。沒有幫助...如果你願意,我可以發佈更新的課程。 –