2015-06-17 38 views
0

我正在研究一个Spring-MVC应用程序,其中我试图在数据库中搜索GroupNotes列表。我的项目中的映射是GroupCanvas与GroupSection的一对多映射,GroupSection与GroupNotes有一对多的映射。由于这些映射,我得到了LazyInitializationException。正如所建议的,我应该将对象转换为DTO对象进行传输。我在网上查了一下,但找不到合适的翻译方式。Spring-MVC,Hibernate:从域对象创建DTO对象

我刚刚创建了一个新的列表以避免错误,但是一个字段仍然给我一个错误。如果有人告诉我如何解决这个错误或将对象转换为DTO对象,以便它们可以传输,我将不胜感激。

控制器代码:

@RequestMapping(value = "/findgroupnotes/{days}/{canvasid}") 
    public @ResponseBody List<GroupNotes> findGroupNotesByDays(@PathVariable("days")int days, @PathVariable("canvasid")int canvasid){ 
     List<GroupNotes> groupNotesList = this.groupNotesService.findGroupNotesByDays(days,canvasid); 

     List<GroupNotes> toSendList = new ArrayList<>(); 
     for(GroupNotes groupNotes : groupNotesList){ 
      GroupNotes toSendNotes = new GroupNotes(); 
      toSendNotes.setMnotecolor(groupNotes.getMnotecolor()); 
      toSendNotes.setNoteCreationTime(groupNotes.getNoteCreationTime()); 
      toSendNotes.setMnotetag(groupNotes.getMnotetag()); 
      toSendNotes.setMnotetext(groupNotes.getMnotetext()); 
      toSendNotes.setAttachCount(groupNotes.getAttachCount()); 
      toSendNotes.setNoteDate(groupNotes.getNoteDate()); 
      toSendList.add(toSendNotes); 
     } 
     return toSendList; 

    } 

GroupNotesDAOImpl:

@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); 
     GroupCanvas groupCanvas = (GroupCanvas) session.get(GroupCanvas.class,mcanvasid); 
     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) { 
      System.out.println("Section name is "+e.getMsectionname()); 
      GroupSection groupSection = (GroupSection) session.get(GroupSection.class,e.getMsectionid()); 
      Query query1 = session.createQuery("from GroupNotes as gn where gn.ownednotes.msectionid=:msectionid and gn.noteCreationTime >:limit"); 
      query1.setParameter("limit", nowMinusDaysAsTimestamp); 
      query1.setParameter("msectionid",e.getMsectionid()); 
      notesList.addAll(query1.list()); 
     } 
// I am getting the data below, but I get JSON errors. 
     for(GroupNotes groupNotes : notesList){ 
      System.out.println("Group notes found are "+groupNotes.getMnotetext()); 
     } 
     return notesList; 
    } 

GroupCanvas模型:

@Entity 
@Table(name = "membercanvas") 
public class GroupCanvas{ 
    @OneToMany(mappedBy = "currentcanvas",fetch=FetchType.LAZY, cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<GroupSection> ownedsection = new HashSet<>(); 

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

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

GroupSection模型:

@Entity 
@Table(name = "membersection") 
public class GroupSection{ 

    @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{ 

    @Id 
    @Column(name="mnoteid") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "mnote_gen") 
    @SequenceGenerator(name = "mnote_gen",sequenceName = "mnote_seq") 
    @org.hibernate.annotations.Index(name = "mnoticesidindex") 
    private int mnoticesid; 

    @Column(name = "mnotetext") 
    private String mnotetext; 

    @Column(name = "mnoteheadline") 
    private String mnotetag; 

    @Column(name = "mnotecolor") 
    private String mnotecolor; 

    @Column(name = "mnoteorder") 
    private double mnoteorder; 

    @Column(name = "attachmentcount") 
    private int attachCount; 

    @Column(name = "notedate") 
    private String noteDate; 

    @Column(name = "uploader") 
    private String uploader; 

    @Column(name = "activeedit") 
    private boolean activeEdit; 

    @Column(name = "notedisabled") 
    private boolean noteDisabled; 

    @Column(name = "noteinactive") 
    private boolean noteInActive; 

    @Column(name = "notecreatoremail") 
    private String noteCreatorEmail; 

    @Column(name = "prefix") 
    private String prefix; 

    @Column(name = "timestamp") 
    private Timestamp noteCreationTime; 

    @Transient 
    private boolean notRead; 

    @Transient 
    private String tempNote; 

    @Transient 
    private String canvasUrl; 

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

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

    public void setOwnednotes(GroupSection ownednotes){this.ownednotes=ownednotes;} 

    @JsonIgnore 
    public int getOwnedSectionId(){ 
     return this.ownednotes.getMsectionid(); 
    } 

    @OneToMany(mappedBy = "mnotedata",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<GroupAttachments> mattachments = new HashSet<>(); 

    public Set<GroupAttachments> getMattachments() { 
     return this.mattachments; 
    } 

    public void setMattachments(Set<GroupAttachments> mattachments) { 

     this.mattachments = mattachments; 
    } 

    @OneToMany(mappedBy = "mhistory",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<GroupNoteHistory> groupNoteHistorySet = new HashSet<>(); 

    public Set<GroupNoteHistory> getGroupNoteHistorySet(){ 
     return this.groupNoteHistorySet; 
    } 

    public void setGroupNoteHistorySet(Set<GroupNoteHistory> groupNoteHistorySet){ 
     this.groupNoteHistorySet = groupNoteHistorySet; 
    } 

    @OneToMany(mappedBy = "unreadNotes",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE) 
    @JsonIgnore 
    private Set<UnreadNotes> unreadNotesSet = new HashSet<>(); 

    public Set<UnreadNotes> getUnreadNotesSet(){ 
     return this.unreadNotesSet; 
    } 

    public void setUnreadNotesSet(Set<UnreadNotes> unreadNotesSet){ 
     this.unreadNotesSet = unreadNotesSet; 
    } 
//getters and setters ignored 
} 

错误日志:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownedSectionId"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownedSectionId"]) 

请让我知道该怎么做,因为有些时候,因为我被困在这个错误。

+0

为什么你有@JsonIgnoreProperties({“ownedSectionId”})'没有这样的pr在你的课堂上运作? –

+0

@NikolayRusev:那是我得到的变量错误,所以我在尝试。我以前没有,但是我遇到了同样的问题。你能帮我解决这个问题吗? –

+0

我试图找到问题所在:) –

回答

1

我认为发生的事情是杰克逊试图根据getter方法序列化层次结构中的所有字段。

@JsonIgnore 
public int getOwnedSectionId(){ 
    return this.ownednotes.getMsectionid(); 
} 

以下方法取代它:

@JsonIgnore 
public int getOwnedSectionId(){ 
    if(this.ownednotes != null) 
     return this.ownednotes.getMsectionid(); 
    return 1; 
} 

为什么杰克逊试图为市场@当序列化它,我没有解释在某些情况下NullPointerException按以下方法抛出JsonIgnore但你可以试用一下我的建议

+0

这工作。非常感谢。但为什么JsonIgnore不被尊重?我一定会标记你的答案。 –

+0

我不确定男人。我必须研究告诉你为什么。我有一些sigguestions,但我不确定。尝试从现场移除@JsonIgnore: '@JsonIgnore 公共GroupSection getOwnednotes(){返回this.ownednotes;}' –

+0

没有帮助。只要你有时间,请帮我理解这一点。非常感谢。 :-) –

1

如果有人告诉过我如何修复这个错误或转换的对象为DTO对象,使他们可以转移我将不胜感激。

我们在此工作中使用DozerMapper

0

不要手动执行映射,您可能需要查看Blaze-Persistence Entity Views,它可以用于使用JPA高效地实现DTO模式。这里一个快速的代码示例如何你的问题可以解决

首先定义你的DTO作为实体视图

@EntityView(GroupNotes.class) 
public interface GroupNoteView { 
    @IdMapping("mnoticesid") int getId(); 

    String getMnotecolor(); 
    String getMnotetag(); 
    String getMnotetext(); 
    String getNoteDate(); 
    Timestamp getNoteCreationTime(); 
    int getAttachCount(); 
} 

接下来你适应你的DAO来利用它

@Override 
public List<GroupNoteView> searchNotesByDays(int days, int mcanvasid) { 
    EntityManager entityManager = // get the entity manager from somewhere 
    CriteriaBuilderFactory cbf = // factory for query building from Blaze-Persistence 
    EntityViewManager evm = // factory for applying entity views on query builders 

    Calendar cal = Calendar.getInstance(); 
    cal.add(Calendar.DAY_OF_YEAR, -days); 
    long daysAgo = cal.getTimeInMillis(); 
    Timestamp nowMinusDaysAsTimestamp = new Timestamp(daysAgo); 

    CriteriaBuilder<GroupNotes> cb = cbf.create(entityManager, GroupNotes.class, "note") 
     .where("noteCreationTime").gt(nowMinusDaysAsTimestamp) 
     .where("ownednotes.ownedcanvas.mcanvasid").eq(mcanvasid); 

    return evm.applySetting(EntityViewSetting.create(GroupNoteView.class), cb) 
     .getResultList(); 
} 

最后的电话代码

@RequestMapping(value = "/findgroupnotes/{days}/{canvasid}") 
public @ResponseBody List<GroupNoteView> findGroupNotesByDays(@PathVariable("days")int days, @PathVariable("canvasid")int canvasid){ 
    return this.groupNotesService.findGroupNotesByDays(days, canvasid); 
}