Избегайте создания дубликатов для функций TImeline в Spring

Я работаю над проектом Spring -MVC, для которого я сейчас работаю над функциональностью Timeline. У меня уже есть базовая инфраструктура, но в настоящее время я имею дело с сопоставлениями и как избежать создания дубликатов для функциональности Timeline.

Ситуация:

В нашем инструменте есть GroupSection, который имеет сопоставление "один ко многим" с GroupNote. Объект GroupNote имеет сопоставление "один ко многим" с вложениями, история.

Что это за функциональность временной шкалы?

В функциональности временной шкалы любой пользователь может перейти в любой момент времени и проверить, как содержимое GroupSection, GroupNotes, вложений и истории.

Как я планирую его реализовать?

У меня есть 4 переменные в каждом из вышеперечисленных объектов для обработки этого. Они Date SavedDate, boolean initialNote, boolean noteModified, boolean latestNote.

Вместе с тем, каждый GroupNote имеет самостоятельное соединение, скоро объяснит это.

Теперь, каждый раз, когда изменяется примечание, измененный флаг имеет значение true. В ночное время я запускаю метод, который проверяет все измененные объекты, и только если объект изменен, он создает дубликат экземпляра для объекта, помещает новую дату в него, отмечает его как последнюю и сохраняет его,

Таким образом, я могу загрузить все объекты для данной даты. И для обычного ежедневного использования будут загружены все заметки, отмеченные как latest.

Всякий раз, когда создается новый объект для сохранения, он соединяется со старым объектом с Cascade.Remove. Это происходит, если пользователь возвращается и удаляет объект с 2015 года, тогда все последующие объекты до настоящего времени также удаляются. Это дает время, подобное поведению.

Проблема:

Теперь, если GroupSection изменен, я создам экземпляр GroupSection и сохраняю его, скопировав свойства из модифицированного GroupSection и пометьте его как последний.

Теперь заметки, которые удерживает это GroupSection, не были изменены, но если я не создаю его повторяющиеся записи, я не увижу никаких заметок, загруженных в интерфейс. Но я хотел бы избежать этого. Как я могу это сделать?

Код наконец:

Модель 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. Тем не менее, я добавлял сопоставления "много-ко-многим", но набор данных не загружается, а также значительно увеличивает сложность, здесь идет процесс . Я все же предпочел бы другой вариант.

Ответ 1

Я не уверен, что мне удалось запустить эту функцию удаления. Для меня жизнеспособной стратегией было бы следовать соотношению "один ко многим" из историческое GroupSection (первое из которых будет удалено из цепочки истории) в соответствующие GroupNotes. Это отношение должно идентифицировать каждую из затронутых GroupNotes соответствующий исторический экземпляр и вызывать удаление такого экземпляра.

Вам может потребоваться собрать ссылки на эти GroupNotes при работе с GroupSections (там, возможно, будут изменения в этом наборе с течением времени, я бы предположил) и очистить результирующий набор в конце, чтобы избежать проверки надписей GroupNotes и выше.

Ответ 2

Я предлагаю изменить связь между 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();

    }

Ответ 3

Как насчет того, что @ManyToOne для GroupNote → GroupSection, вместо ссылки GroupNote в GroupSection?

При изменении любого GroupSection вы можете просто обновить GroupSection и дату его изменения. Если вы хотите, чтобы GroupNote также обновлялся, вы можете обрабатывать его на уровне сервиса, используя отдельный запрос.