我正在開發Spring-MVC項目,目前我正在使用它的時間線功能。我有一個基本的基礎架構已經在進行中,但目前,我正在處理映射,以及如何避免爲時間軸功能創建重複項。避免在Spring中爲TImeline功能創建重複項
現狀:
在我們的工具,有GroupSection具有一個一對多的映射與GroupNote。 GroupNote對象與附件,歷史記錄具有一對多映射。
什麼是時間軸功能?
在時間軸功能中,任何用戶都可以隨時跳轉,並檢查GroupSection,GroupNotes,附件和歷史記錄的內容。
我打算如何實施它?
我在上述每個對象中都有4個變量來處理這個。它們是Date SavedDate
,boolean initialNote
,boolean noteModified
,boolean latestNote
。
除此之外,每個GroupNote都有一個自連接,將很快解釋它。
現在,每次修改Note時,修改標誌都會設置爲true。在晚上,我運行一個方法,它檢查所有修改的對象,並且只有當對象被修改時,它纔會爲該對象創建一個重複的實例,將新的Date放入它中,將其標記爲最新的一個,並將其保留。
這樣,我可以加載給定日期的所有對象。而對於正常的日常使用,所有標記爲latest
的筆記都將被加載。
每當爲持久性創建一個新對象時,就會自動與舊對象進行自我連接,使用Cascade.Remove
。這樣做的是,如果用戶返回並從2015年移除該對象,則直到現在的所有後續對象也將被移除。這給了一個像時間一樣的行爲。
問題:
現在,如果一個GroupSection被修改,那麼我將創建GroupSection的實例,並堅持它,通過複製修改GroupSection特性,並將其標記爲最新。
現在,GroupSection所持有的註釋未被修改,但如果我不創建其重複條目,那麼在前端中將看不到任何Notes。但我想避免這種情況。我怎樣才能做到這一點?
代碼最後:
GroupSection型號:
@Entity
@Table(name = "membersection")
public class GroupSection {
@Column(name = "section_save_date", columnDefinition = "date")
private Date secnSavedDate;
@Column(name = "initial_section", columnDefinition = "boolean default true")
private boolean initialSection;
@Column(name = "section_modified", columnDefinition = "boolean default false")
private boolean sectionModified;
@Column(name = "latest_section", columnDefinition = "boolean default false")
private boolean latestSection;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "owned_section_id", nullable = true)
private GroupSection primarySection;
@OneToMany(mappedBy = "primarySection", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private Set<GroupSection> groupSectionSet = new HashSet<>();
@OneToMany(mappedBy = "ownednotes", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JsonIgnore
private Set<GroupNotes> sectionsnotes = new HashSet<>();
}
GroupNotes型號:
@Entity
@Table(name = "groupnotes")
public class GroupNotes implements Serializable {
@Column(name = "note_save_date", columnDefinition = "date")
private Date noteSavedDate;
@Column(name = "initial_note", columnDefinition = "boolean default true")
private boolean initialNote;
@Column(name = "note_modified", columnDefinition = "boolean default false")
private boolean noteModified;
@Column(name = "latest_note", columnDefinition = "boolean default false")
private boolean latestNote;
@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<>();
}
GroupSectionDAOImpl:
@Override
@Transactional(readOnly = true)
public List<GroupSection> listGroupSectionByCanvasAndDate(int mcanvasid, Date dateToLoad) {
Session session = this.sessionFactory.getCurrentSession();
org.hibernate.Query query = session.createQuery("From GroupSection as msection where " +
"msection.currentcanvas.mcanvasid=:mcanvasid and " +
"msection.secnSavedDate>:dateToLoad " +
" and msection.sectionDisabled=false and msection.latestSection=true and msection.sectionInActive=false order by msection.secnSavedDate asc");
query.setParameter("mcanvasid", mcanvasid);
query.setParameter("dateToLoad",dateToLoad);
return query.list();
}
@Override
public List<GroupSection> listModifiedSectionsForYesterday() {
Session session = this.sessionFactory.getCurrentSession();
Calendar cal = Calendar.getInstance();
Query query = session.createQuery("from GroupSection as gs where gs.sectionModified=true and gs.latestSection=true and gs.secnSavedDate<:loadDate order by gs.secnSavedDate asc");
query.setParameter("loadDate",cal.getTime());
return query.list();
}
以上DAO方法給我修改的部分從昨日起,或最後一次修改的部分,而對於給定的日期同樣的部分。我也有類似的方法GroupNotesDAOImpl
GroupSectionServiceImpl:
@Override
public List<GroupSection> retrieveModifiedSections() {
List<GroupSection> groupSectionList = this.groupSectionDAO.listModifiedSectionsForYesterday();
for (GroupSection yesterdaySection : groupSectionList) {
yesterdaySection.setLatestSection(false);
this.groupSectionDAO.updateGroupSection(yesterdaySection);
GroupSection newDaySection = new GroupSection();
BeanUtils.copyProperties(yesterdaySection, newDaySection);
newDaySection.setInitialSection(false);
newDaySection.setSectionModified(false);
newDaySection.setLatestSection(true);
newDaySection.setMsectionid(0);
newDaySection.setSortedSectionSet(null);
newDaySection.setSecnSavedDate(Calendar.getInstance().getTime());
int sectionSavedId = directAddGroupSection(newDaySection, yesterdaySection.getCurrentCanvasId());
List<GroupNotes> groupNotesList = this.groupNotesService.directListGroupNotesBySectionIdForCanvasCopying(yesterdaySection.getMsectionid());
for(GroupNotes groupNotes : groupNotesList){
Problem --> // No option but to create duplicates.
}
}
return this.groupSectionDAO.listModifiedSectionsForYesterday();
}
我希望這個問題是可以理解的。如果有任何疑問,請讓我知道。
編輯
一個策略,我能想到的與GroupSection和GroupNotes之間的許多一對多的映射是怎麼回事。不幸的是,很多後端以及前端代碼已經在GroupSection和GroupNotes之間建立了一對多映射。 儘管如此,我確實添加了多對多的映射,但數據集沒有被加載,也增加了很多複雜性,這是一個正在進行的問題here。我仍然會選擇其他選項。
hm ....關於分離實體,將id設置爲null,如此處所述進行所需的更改和持續保存呢? http://stackoverflow.com/questions/11625096/cloning-jpa-entity – ivanenok
@ MaximS.Ivanov:這只是創建一個重複的,我想明確避免的問題。 –