背景:
我们有这么一个需求:我们的系统要求我们把页面展示的表格字段全部保存在数据库里,就是客户可以根据自己的需求来自定义自已想要看的那些字段,然后这部书数据就持久化到我们的数据库里。如果客户可以自定义一个grid_view(table):名字为view1, 那view1下会关联到不同的column(gridviewqueryItem表),同时我们也会把按照呐个字段group,filter, sort都持久化到这张表理去。这样就形成了一个一对多的关系,然后对于gridviewqueryitem表,我们就用了一个queryItemType字段来区别这条记录是columns还是group还是filter还是sort。然后当我们从GridView中取出这个columnList的时候,我们根据queryItemType的值来loop这个columnlist,并且分类得到groupsList,filterList还是SortList。 美国的同事看到这个代码,坚决说要重写,不能写的这么啰嗦。说可以利用JPA 的单表继承来做:single table inheritance。 虽然不情愿,但是还是得这么干。否则codeview不过关,代码checkin不了。
方案:
单表继承example:
http://www.thejavageek.com/2014/05/14/jpa-single-table-inheritance-example/
原先我们的表结构设计师这样子的:
@Entity
public class GridView {
@Id
@GeneratedValue(generator = "GRID_VIEW_ID_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "GRID_VIEW_ID_SEQ", sequenceName = "GRID_GENERIC_ID_SEQ", allocationSize = 1)
private Long id;
@Column(name = "GRID_CONFIG_ID")
private Long gridId;
@Column(name = "NAME")
private String name;
@ManyToOne
@JoinColumn(name = "USER_ID")
private User user;
@OneToMany(mappedBy = "gridView", fetch = FetchType.EAGER, cascade = CascadeType.ALL )
private List<GridViewQueryItem> gvqiList;
后来就改成了这样:
@Entity
public class GridView {
@Id
@GeneratedValue(generator = "GRID_VIEW_ID_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "GRID_VIEW_ID_SEQ", sequenceName = "GRID_GENERIC_ID_SEQ", allocationSize = 1)
private Long id;
@Column(name = "GRID_CONFIG_ID")
private Long gridId;
@Column(name = "NAME")
private String name;
@ManyToOne
@JoinColumn(name = "USER_ID")
private User user;
@OneToMany(mappedBy = "gridViewCol", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@Where(clause="QUERY_ITEM_TYPE='columns'")
private List<GridViewQueryItemColumns> gvqiColumns;
@OneToMany(mappedBy = "gridViewSort", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true )
@Where(clause="QUERY_ITEM_TYPE='sorts'")
private List<GridViewQueryItemSorts> gvqiSorts;
@OneToMany(mappedBy = "gridViewFilter", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true )
@Where(clause="QUERY_ITEM_TYPE='filters'")
private List<GridViewQueryItemFilters> gvqiFilters;
@OneToMany(mappedBy = "gridViewGroup", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true )
@Where(clause="QUERY_ITEM_TYPE='groups'")
private List<GridViewQueryItemGroups> gvqiGroups;
主要这里的Where语句刚开始是没有的,在没有Where条件的情况下,我的项目做save操作的时候,能够成功,但是作查询的时候,就出异常了。
原本按我们之前的理解是JPA会自动根据查询出来的queryItemType的值,来匹配到对应的List上,比如:queryItemType=columns,那么当我们拿到查询结果的时候,columns相关的数据就会自动封装到gvqiColumns 这个集合里去,但是事实却没有,它把所有的数据全部都整合到一个gvqiColumns的集合里去了,然后我们要取里面的数据时候,就是抛WrongClassException的异常。
后来google大神帮我解决了这个问题:
http://stackoverflow.com/questions/13972633/jpa-mapping-for-one-to-many-with-inheritance-mapping
就是加了Where语句,并且记住了clause里的String字符串是
"QUERY_ITEM_TYPE='groups'",不要忘记了单引号:)
其实在解决了这个问题之后,又有了其他的问题。
比如我想更新gridview下面的columns等信息的时候,一直更新不成功,它只会新增新的column,但是我要的是删除之前的,再插入新的。但是老是不成功,后来就加了
orphanRemoval = true
但是还是不行,错误提示:
引用
A collection with cascade=“all-delete-orphan” was no longer referenced by the owning entity instance
后来google了这个链接:
http://stackoverflow.com/questions/9430640/a-collection-with-cascade-all-delete-orphan-was-no-longer-referenced-by-the-ow
然后通过
if(CollectionUtils.isEmpty(gridView.getGvqiColumns())) {//save
gridView.setGvqiColumns(gvqiColumns);
} else { //update
[color=red]gridView.getGvqiColumns().clear();
gridView.getGvqiColumns().addAll(gvqiColumns);[/color]
}
标红的两行代码解决了update的问题。
记录的比较零散。。。权且给自己做个笔记吧
----EOF----
分享到:
相关推荐
Apress.Pro.JPA.2.2nd.Edition.Oct.2013
仓库管理系统,SpringBoot+Spring Data JPA+.....
问题描述 用SpringBoot + Spring Data JPA操作数据库 项目启动的时候 报了一个错 SpringBoot的版本是2.2.6.RELEASE org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...
管理系统系列--仓库管理系统,SpringBoot+Spring Data JPA+.....
详细的jpa-java持久化API.ppt
JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解....
SpringBoot+JPA+LayUI商城系统源码
赠送jar包:hibernate-jpa-2.1-api-1.0.2.Final.jar; 赠送原API文档:hibernate-jpa-2.1-api-1.0.2.Final-javadoc.jar; 赠送源代码:hibernate-jpa-2.1-api-1.0.2.Final-sources.jar; 赠送Maven依赖信息文件:...
02_JPA详解_JPA开发环境和思想介绍.zip 02_JPA详解_JPA开发环境和思想介绍.zip
Spring Data JPA中文文档[1.4.3].zip
jpa开发手册[文].pdf
springJpa单标递归树形结构
1、基于SpringBoot+Thymeleaf+JPA的博客系统源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 ...
spring-data-jpa-1.1.0.RC1.zip
Spring Data JPA中文文档[1.4.3].pdf
本项目使用Maven+SpringBoot+springDataJPA,实现单表的增删改查
EJB_JPA数据库持久层开发详解.doc