来自一个表的两个@ElementCollections,带有鉴别器列样式实现

时间:2017-11-03 12:09:00

标签: java spring-mvc jpa

首先,我不知道这是否可行,因为我认为该解决方案将两个现有的JPA功能合并为一个:元素集合和鉴别器列。

如下所述,我知道如何使用ONLY鉴别器来实现解决方案,但考虑到下述要求,这将是一个繁琐的实现。

我有一个Wiget pojo,它将有可选的过滤器来减少显示的内容。目前,我有两个pojos可以用作过滤器(会有更多)下面的类是类的简化版本(它们包含更多,但我已经将它们剥离到相关信息) :

细胞

@Entity
@Table(name = "Cell")
public class Cell implements java.io.Serializable {

  private Integer cellId;
  private String cell;
  private String description;
  ...
}    

任务:

@Entity
@Table(name = "Task")
public class Task implements java.io.Serializable {

  private Integer taskId;
  private String task;
  ...
}

我想要实现的是一个表(@CollectionTable?),其中包含对这两个pojos的引用,而不需要加入pojo"。除非我误解了,否则这就是@ElementCollection的重点。

要过滤的过滤器pojos的数量将被扩展,并且可能包含系统中已有的大部分pojos,我不想创建多个" join&# 34; pojos只是为了维护所有可能的过滤器,当我可以改为维护一些静态整数,以类似于鉴别器列工作的方式引用pojo类型

所以在Widget中,它看起来像是:

窗口小部件:

@Entity
@Table(name = "Widget")
public class Widget {

  private Integer widgetId;
  private String colour;
  private String description;
  private Date fromDate;
  private Date toDate;
  private Set<Cell> cellsFilter = new HashSet<Cell>();
  private Set<Task> tasksFilter = new HashSet<Task>();
  ...
}

过滤器(cellsFilter和tasksFilter)是可选的(根本没有过滤器)。

表示@CollectionTable的表格如下:

╔═════════════════╗
║  WidgetFilters  ║
╠═════════════════╣
║ id              ║
║ widgetId        ║ <- Should join to the Widget.widgetId column
║ pojoType        ║ <- Integer, 1 = cell, 2 = task etc...
║ pojoId          ║ <- Should join on the id of the cell or task (or other)
╚═════════════════╝

我已经使用@DiscriminatorColumn做了类似的事情,但这需要我创建一个抽象的Filter对象,CellFilter和TaskFilter(最后创建的每个其他过滤器都有一个)。

我能找到的最接近的例子是https://en.wikibooks.org/wiki/Java_Persistence/ElementCollection但是这只链接一个pojo类型(Phone)和一个join(雇员id),我需要根据pojoType链接到pojoId到正确的pojo类型列和基于widgetId将其连接到Widget。

仅供参考,我已经尝试过加入where子句,各种组合等内容:

@ElementCollection(targetClass=Cell.class)
@JoinTable(
  name="WidgetFilter", 
  joinColumns=@JoinColumn(name="widgetId", referencedColumnName="widgetId"),
  inverseJoinColumns=@JoinColumn(name="pojoId", referencedColumnName="cellId")
)
@Where(clause = "pojoType = 1")
public Set<Cell> getCellsFilter() {

  return cellsFilter;
}

对于谷歌而言,这是一个难以理解的概念,因为所有类似的,但不完全相同的#34;答案可用

如果不可能,那很好,至少我知道如何继续,但如果有人已经实现了这一点,那么任何帮助都会受到赞赏。

我目前的解决方案:

我能想到这样做的唯一方法是创建一个代表WidgetFilter表行的Filter pojo,并使Widget pojo包含将List<Filters>解析为正确类型的逻辑(不包含任何内容)花哨的注释)就像这样......

窗口小部件:

@Entity
@Table(name = "Widget")
public class Widget {

  private Integer widgetId;
  private String colour;
  private String description;
  private Date fromDate;
  private Date toDate;
  private Set<Filter> filters = new HashSet<Filter>();
  private Set<Cell> cellsFilter = new HashSet<Cell>();
  private Set<Task> tasksFilter = new HashSet<Task>();
  ...
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "filter")
  public List<Filter> getFilters() {

    return this.filters;      
  }

  public void setFilters(List<Filter> filters) {

    this.filters = filters;
    setCellFilters(filters);
    setTaskFilters(filters);
  }

  @Transient
  public List<Cell> getCellsFilter() {

    return this.cellsFilter;
  }

  public void setCellsFilter() {

    List<Filter> cellFilters = filters.stream().filter(f -> f.getPojoType().intValue() == Filter.CELL).collect(Collectors.toList());
    // get List<Cell> from database from List<Filter>
  }

  @Transient
  public List<Task> getTasksFilter() {

    return this.tasksFilter;
  }

  public void setTasksFilter() {

    List<Filter> taskFilters = filters.stream().filter(f -> f.getPojoType().intValue() == Filter.TASK).collect(Collectors.toList());
    // get List<Task> from database from List<Filter>
  }
  ...
}

过滤

@Entity
@Table(name = "Filter")
public class Filter{

  public static final int CELL = 1;
  public static final int TASK = 2;

  private Integer filterId;
  private Widget widget;
  private Integer pojoType;
  private Integer pojoId;
  ...
}

干杯,
史蒂夫。

0 个答案:

没有答案