我正在开发一个Spring-MVC项目,我目前正在使用Timeline功能。我有一个基本的基础设施正在进行中,但目前,我正在处理映射,以及如何避免为时间轴功能创建重复项。
情况:
在我们的工具中,有GroupSection,它与GroupNote具有一对多的映射。 GroupNote对象具有“附件”,“历史记录”的一对多映射。
这个时间轴功能是什么?
在时间轴功能中,任何用户都可以在任何时间点跳转并检查GroupSection,GroupNotes,附件和历史记录的内容。
我打算如何实施呢?
我在上述每个对象中都有4个变量来处理它。它们是Date SavedDate
,boolean initialNote
,boolean noteModified
,boolean latestNote
。
除此之外,每个GroupNote都有一个自我加入,很快就会解释它。
现在,每次修改Note时,修改后的标志都设置为true。在晚上,我运行一个方法,它检查所有修改过的对象,并且只有在修改了对象时,它才会为Object创建一个重复的实例,将新的Date放入其中,将其标记为最新的,然后保留它。 。
这样,我可以加载给定日期的所有对象。对于正常的日常使用,将加载标记为latest
的所有注释。
每当为持久性创建新对象时,它都会使用Cascade.Remove
与旧对象自行连接。这样做的是,如果用户返回并从2015年移除对象,则所有后续对象也将被删除。这给了时间就像行为。
问题:
现在,如果修改了GroupSection,那么我将创建一个GroupSection实例并通过从修改后的GroupSection复制属性来保留它,并将其标记为最新。
现在,GroupSection持有的Notes没有被修改,但如果我不创建它的重复条目,那么我将不会在前端看到任何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。我还是会选择其他一些选择。
答案 0 :(得分:0)
我不确定我是否应该触发此删除功能。 对我来说,一个可行的策略是遵循一对多的关系 历史GroupSection(历史链的第一个被删除)到相关的GroupNotes。此关系需要识别每个受影响的GroupNotes 相应的历史实例并导致删除此类实例。
您可能需要在处理GroupSections时收集对这些GroupNotes的引用(可能会随着时间的推移而更改此集合,我假设) 并在最后清理结果集以避免检查GroupNotes obver和over。
答案 1 :(得分:0)
我建议将GroupSection和GroupNotes之间的关联更改为多对多,以避免重复的组注。
@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<>();
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "groupsection_groupnote", joinColumns = {
@JoinColumn(name = "GROUP_SECTION_ID", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "GROUP_NOTE_ID",
nullable = false, updatable = false) })
@JsonIgnore
private Set<GroupNotes> sectionsnotes = new HashSet<>();
}
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());
newDaySection.setGroupNotesSet(groupNotesList);
}
return this.groupSectionDAO.listModifiedSectionsForYesterday();
}
答案 2 :(得分:0)
我认为你应该试试这个想法。
@ManyToOne for GroupNote -> GroupSection,而不是在GroupSection中引用GroupNote?