首先,我不知道这是否可行,因为我认为该解决方案将两个现有的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;
...
}
干杯,
史蒂夫。