Oracle Jpa-Hibernate manytomy do many插入到联接表中

Oracle Jpa-Hibernate manytomy do many插入到联接表中,oracle,hibernate,jpa-2.1,Oracle,Hibernate,Jpa 2.1,我遵循了manytomy在WorkDay(有注释manytomy)和事件之间的关系 工作日实体 为清晰起见,附上用户界面表格 当我第一次按下带有运行图标的时钟时,它在bean中表示“创建事件并开始工作日”,调用以下方法: public void startEvent() { stopLastActiveEvent(); Event creationEvent = new Event(workDay.getDay().getDay(), selectedEventType, se

我遵循了
manytomy
WorkDay
(有注释manytomy)和
事件之间的关系

工作日实体

为清晰起见,附上用户界面表格

当我第一次按下带有运行图标的时钟时,它在bean中表示“创建事件并开始工作日”,调用以下方法:

public void startEvent() {
    stopLastActiveEvent();
    Event creationEvent = new Event(workDay.getDay().getDay(), selectedEventType, selectedEventType.getTitle(),
            LocalDateTime.now());
    String addEventMessage = workDay.addEvent(creationEvent);
    if (Objects.equals(addEventMessage, "")) {
        em.persist(creationEvent);
        if (workDay.isNoWork()
                && !creationEvent.getType().getCategory().equals(EventCategory.NOT_INFLUENCE_ON_WORKED_TIME)) {
            startWork();
        }
        em.merge(workDay);
    } else {
        Notification.warn("Невозможно создать событие", addEventMessage);
    }
    cleanAfterCreation();
}

public String addEvent(Event additionEvent) {
    if (!additionEvent.getType().getCategory().equals(NOT_INFLUENCE_ON_WORKED_TIME)
            && isPossibleTimeBoundaryForEvent(additionEvent.getStartTime(), additionEvent.getEndTime())) {
        events.add(additionEvent);
        changeTimeBy(additionEvent);
    } else {
        return "Пересечение временых интервалов у событий";
    }
    Collections.sort(events, new EventComparator());
    return "";
}

private void startWork() {
    workDay.setComingTime(workDay.getLastWorkEvent().getStartTime());
    workDay.setState(WorkDayState.WORKING);
}
在日志中,我看到:

  • 插入到事件表中
  • 更新工作日表
  • 插入工作日事件表
  • 在UI上,仅更新了附加的框架。看起来总是很好。。当前
    WorkDay
    对象在
    events
    集合中有一个元素,并且所有数据都插入到
    DB
    中。。但如果这次编辑事件行

    事件行侦听器:

    public void onRowEdit(RowEditEvent event) {
        Event editableEvent = (Event) event.getObject();
        LocalDateTime startTime = fixDate(editableEvent.getStartTime(), editableEvent.getDay());
        LocalDateTime endTime = fixDate(editableEvent.getEndTime(), editableEvent.getDay());
        if (editableEvent.getState().equals(END) && startTime.isAfter(endTime)) {
            Notification.warn("Невозможно сохранить изменения", "Время окончания события больше времени начала");
            refreshEvent(editableEvent);
            return;
        }
        if (workDay.isPossibleTimeBoundaryForEvent(startTime, endTime)) {
            editableEvent.setStartTime(startTime);
            editableEvent.setEndTime(endTime);
            workDay.changeTimeBy(editableEvent);
            em.merge(workDay);
            em.merge(editableEvent);
        } else {
            refreshEvent(editableEvent);
            Notification.warn("Невозможно сохранить изменения", "Пересечение временых интервалов у событий");
        }
    }
    
    工作日事件
    中插入具有相同
    工作日id
    事件id
    数据的新行。如果编辑行,则再插入一行,以此类推。。在结果中,我在
    work\u day\u event
    表中有几个相等的行。为什么会发生这种情况


    我认为简单的解决方案是删除多对多关系上的级联,然后手动完成这项工作。我看你已经在做多余的事了。所以,试着把你移除

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    

    更改
    级联类型。将所有
    更改为
    级联类型。将
    事件的
    合并到
    工作日实体中

    使用此代码

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
    
    而不是

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    

    不要使用
    ArrayList
    ,请使用
    HashSet
    。因为
    ArrayList
    允许重复

    有关CasecadeType的更多信息,请按照教程进行操作:


  • 在工作日内,您已经为事件设置了
    CascadeType.ALL
    。这意味着不需要单独保存事件本身。保存工作日应完成以下工作:
    em.merge(workDay)
    @XtremeBiker,是的,但它没有解决我的问题。您是否尝试在工作日活动中使用单独的映射器实体类?请尝试在询问.ty以获取答案时遵守规则。我尝试过使用
    CascadeType.MERGE
    而不是
    CascadeType.ALL
    ,我也尝试过使用
    Set
    ,但没有解决我的问题。@HAYMbl4如果可能,您可以通过github共享您的项目。我将尝试解决您的问题。@HAYMbl4您可以通过查看来更好地理解。我认为问题可能是我使用的是
    EntityManager
    ,而不是
    manytomy
    @HAYMbl4。同样的问题也会发生。请检查这个链接并给我更新。那我就试试你的代码。
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
    
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)