oracle – Jpa – Hibernate ManyToMany做很多插入连接表

前端之家收集整理的这篇文章主要介绍了oracle – Jpa – Hibernate ManyToMany做很多插入连接表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我遵循WorkDay(具有注释ManyToMany)和Event之间的ManyToMany关系

WorkDay entity

  1. @Entity
  2. @Table(name = "WORK_DAY",uniqueConstraints = { @UniqueConstraint(columnNames = { "WORKER_ID","DAY_ID" }) })
  3. @NamedQueries({
  4. @NamedQuery(name = WorkDay.GET_WORK_DAYS_BY_MONTH,query = "select wt from WorkDay wt where wt.worker = :worker and to_char(wt.day.day,'yyyyMM') = :month) order by wt.day"),@NamedQuery(name = WorkDay.GET_WORK_DAY,query = "select wt from WorkDay wt where wt.worker = :worker and wt.day = :day") })
  5. public class WorkDay extends SuperClass {
  6.  
  7. private static final long serialVersionUID = 1L;
  8.  
  9. public static final String GET_WORK_DAYS_BY_MONTH = "WorkTimeDAO.getWorkDaysByMonth";
  10. public static final String GET_WORK_DAY = "WorkTimeDAO.getWorkDay";
  11.  
  12. @ManyToOne(fetch = FetchType.LAZY)
  13. @JoinColumn(name = "WORKER_ID",nullable = false)
  14. private Worker worker;
  15.  
  16. @ManyToOne(fetch = FetchType.LAZY)
  17. @JoinColumn(name = "DAY_ID",nullable = false)
  18. private Day day;
  19.  
  20. @Column(name = "COMING_TIME")
  21. @Convert(converter = LocalDateTimeAttributeConverter.class)
  22. private LocalDateTime comingTime;
  23.  
  24. @Column(name = "OUT_TIME")
  25. @Convert(converter = LocalDateTimeAttributeConverter.class)
  26. private LocalDateTime outTime;
  27.  
  28. @Enumerated(EnumType.STRING)
  29. @Column(name = "STATE",length = 16,nullable = false)
  30. private WorkDayState state = WorkDayState.NO_WORK;
  31.  
  32. @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
  33. @JoinTable(name = "WORK_DAY_EVENT",joinColumns = {
  34. @JoinColumn(name = "WORK_DAY_ID",nullable = false)},inverseJoinColumns = {
  35. @JoinColumn(name = "EVENT_ID",nullable = false)})
  36. @OrderBy(value = "startTime desc")
  37. private List<Event> events = new ArrayList<>();
  38.  
  39. protected WorkDay() {
  40. }
  41.  
  42. public WorkDay(Worker worker,Day day) {
  43. this.worker = worker;
  44. this.day = day;
  45. this.state = WorkDayState.NO_WORK;
  46. }
  47. }

Event entity

  1. @Entity
  2. @Table(name = "EVENT")
  3. public class Event extends SuperClass {
  4.  
  5. @Column(name = "DAY",nullable = false)
  6. @Convert(converter = LocalDateAttributeConverter.class)
  7. private LocalDate day;
  8.  
  9. @ManyToOne(fetch = FetchType.LAZY)
  10. @JoinColumn(name = "TYPE_ID",nullable = false)
  11. private EventType type;
  12.  
  13. @Column(name = "TITLE",nullable = false,length = 128)
  14. private String title;
  15.  
  16. @Column(name = "DESCRIPTION",nullable = true,length = 512)
  17. private String description;
  18.  
  19. @Column(name = "START_TIME",nullable = false)
  20. @Convert(converter = LocalDateTimeAttributeConverter.class)
  21. private LocalDateTime startTime;
  22.  
  23. @Column(name = "END_TIME",nullable = true)
  24. @Convert(converter = LocalDateTimeAttributeConverter.class)
  25. private LocalDateTime endTime;
  26.  
  27. @Enumerated(EnumType.STRING)
  28. @Column(name = "STATE",length = 16)
  29. private EventState state;
  30.  
  31. protected Event() {
  32. }
  33. }

为了清晰起见,附加的UI表单

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

  1. public void startEvent() {
  2. stopLastActiveEvent();
  3. Event creationEvent = new Event(workDay.getDay().getDay(),selectedEventType,selectedEventType.getTitle(),LocalDateTime.now());
  4. String addEventMessage = workDay.addEvent(creationEvent);
  5. if (Objects.equals(addEventMessage,"")) {
  6. em.persist(creationEvent);
  7. if (workDay.isNoWork()
  8. && !creationEvent.getType().getCategory().equals(EventCategory.NOT_INFLUENCE_ON_WORKED_TIME)) {
  9. startWork();
  10. }
  11. em.merge(workDay);
  12. } else {
  13. Notification.warn("Невозможно создать событие",addEventMessage);
  14. }
  15. cleanAfterCreation();
  16. }
  17.  
  18. public String addEvent(Event additionEvent) {
  19. if (!additionEvent.getType().getCategory().equals(NOT_INFLUENCE_ON_WORKED_TIME)
  20. && isPossibleTimeBoundaryForEvent(additionEvent.getStartTime(),additionEvent.getEndTime())) {
  21. events.add(additionEvent);
  22. changeTimeBy(additionEvent);
  23. } else {
  24. return "Пересечение временых интервалов у событий";
  25. }
  26. Collections.sort(events,new EventComparator());
  27. return "";
  28. }
  29.  
  30. private void startWork() {
  31. workDay.setComingTime(workDay.getLastWorkEvent().getStartTime());
  32. workDay.setState(WorkDayState.WORKING);
  33. }

在日志中我看到:

>插入事件表
>更新work_day表
>插入work_day_event表

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

事件行侦听器:

  1. public void onRowEdit(RowEditEvent event) {
  2. Event editableEvent = (Event) event.getObject();
  3. LocalDateTime startTime = fixDate(editableEvent.getStartTime(),editableEvent.getDay());
  4. LocalDateTime endTime = fixDate(editableEvent.getEndTime(),editableEvent.getDay());
  5. if (editableEvent.getState().equals(END) && startTime.isAfter(endTime)) {
  6. Notification.warn("Невозможно сохранить изменения","Время окончания события больше времени начала");
  7. refreshEvent(editableEvent);
  8. return;
  9. }
  10. if (workDay.isPossibleTimeBoundaryForEvent(startTime,endTime)) {
  11. editableEvent.setStartTime(startTime);
  12. editableEvent.setEndTime(endTime);
  13. workDay.changeTimeBy(editableEvent);
  14. em.merge(workDay);
  15. em.merge(editableEvent);
  16. } else {
  17. refreshEvent(editableEvent);
  18. Notification.warn("Невозможно сохранить изменения","Пересечение временых интервалов у событий");
  19. }
  20. }

到work_day_event插入具有相同work_day_id和event_id数据的新行.并且如果编辑行,则执行一次插入等操作.在结果中,我在work_day_event表中有几个等于行.为什么会这样?

link to github project repository(look ver-1.1.0-many-to-many-problem branch)

对于WokrDay实体中的事件,将CascadeType.ALL更改为CascadeType.MERGE

使用此代码

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

代替

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

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

有关CasecadeType的更多信息,请按照教程:

> Hibernate JPA Cascade Types
> Cascading best practices

猜你在找的Oracle相关文章