这两天我在想做一个东西,需要将文章保存的同时,将文章相关的表也一起保存,想用sping data jpa来实现建表,和保存;
总结一些我遇到的问题
遇到第一个问题
我是用的Spring Initializr 来构建的springboot项目;
但是这个默认的是新的mysql驱动,名字改成了com.mysql.cj.jdbc.Driver
,需要将msyql的包版本改成自己需要的
第二个问题
自动建表的引擎问题
spring data jpa 默认的引擎为MyISAM
这里改成InnoDB
配置application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/hmp?characterEncoding=utf-8
username: root
password: root
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #不加这句则默认为MyISAM引擎
@Table(name="hmp_article")
public class Article implements Serializable{
@Id
private String id;//ID
@ManyToOne(fetch=FetchType.LAZY)
private Column column;//专栏
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.DETACH},fetch=FetchType.LAZY)
private List<Channel> channel;//所属频道
private String username;//用户名
private String title;//标题
private String content;//文章正文
private java.util.Date createTime;//发表日期
private java.util.Date updateTime;//修改日期
private String isPublic;//是否公开
private String isTop;//是否置顶
private Integer visits;//浏览量
private Integer comment;//评论数
private String url;//URL
@Entity
@Table(name="hmp_channel")
public class Channel implements Serializable {
@Id
private String id;//ID
@ManyToMany(cascade = CascadeType.DETACH,fetch=FetchType.LAZY,mappedBy = "channel")
private List<Article> article;
private String name;//频道名称
private String state;//状态
@Entity
@Table(name="hmp_column")
public class Column implements Serializable{
@Id
private String id;//ID
@OneToMany(cascade = CascadeType.DETACH,mappedBy = "column",fetch=FetchType.LAZY)
private List<Article> article;
private String name;//专栏名称
private String summary;//专栏简介
private java.util.Date createTime;//创建日期
private java.util.Date updateTime;//更新日期
private String state;//状态
这时类的关系就配置好了
表也正常创建出来了
也能添加对象
但是查询出了问题
org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: Infinite recursion (StackOverflowError);
nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (StackOverflowError) (through reference chain:
org.bighamapi.hmp.pojo.Column_$$_jvst647_3["article"]->org.hibernate.collection.internal.PersistentBag[0]->org.bighamapi.hmp.pojo.Article["column"]->org.bighamapi.hmp.pojo.Column_$$_jvst647_3["article"]->org.hibernate.collection.internal.PersistentBag[0]->org.bighamapi.hmp.pojo.Article["column"]->org.bighamapi.hmp.pojo.Column_$$_jvst647_3["article"]->org.hibernate.collection.internal.PersistentBag[0]->org.bighamapi.hmp.pojo.Article["column"]->org.bighamapi.hmp.pojo.Column_$$_jvst647_3["article"]->org.hibernate.collection.internal.PersistentBag[0]->
我找了一堆资料,后来在一篇博客 https://blog.csdn.net/u010138825/article/details/83095026 中知道了这就是json的无限递归;@ManyToMany多对多关系的问题
两个对象互相调用,你中有我我中有你
解决办法是
实体类加上 @JsonIgnoreProperties(ignoreUnknown = true, value =
{"hibernateLazyInitializer", "handler", "fieldHandler"})
在依赖的属性上加上 @JsonIgnoreProperties(ignoreUnknown = true, value = {""})
最终的实体类
@Entity
@Table(name="hmp_article")
@JsonIgnoreProperties(ignoreUnknown = true, value =
{"hibernateLazyInitializer", "handler", "fieldHandler"})
public class Article implements Serializable{
@Id
private String id;//ID
@ManyToOne(fetch=FetchType.LAZY)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"article"})
private Column column;//专栏
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.DETACH},fetch=FetchType.LAZY)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"article"})
private List<Channel> channel;//所属频道
private String username;//用户名
private String title;//标题
private String content;//文章正文
private java.util.Date createTime;//发表日期
private java.util.Date updateTime;//修改日期
private String isPublic;//是否公开
private String isTop;//是否置顶
private Integer visits;//浏览量
private Integer comment;//评论数
private String url;//URL
@Entity
@Table(name="hmp_channel")
@JsonIgnoreProperties(ignoreUnknown = true, value =
{"hibernateLazyInitializer", "handler", "fieldHandler"})
public class Channel implements Serializable {
@Id
private String id;//ID
@ManyToMany(cascade = CascadeType.DETACH,fetch=FetchType.LAZY,mappedBy = "channel")
@JsonIgnoreProperties(ignoreUnknown = true, value = {"channel"})
private List<Article> article;
private String name;//频道名称
private String state;//状态
@Entity
@Table(name="hmp_column")
@JsonIgnoreProperties(ignoreUnknown = true, value =
{"hibernateLazyInitializer", "handler", "fieldHandler"})
public class Column implements Serializable{
@Id
private String id;//ID
@OneToMany(cascade = CascadeType.DETACH,mappedBy = "column",fetch=FetchType.LAZY)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"column"})
private List<Article> article;
private String name;//专栏名称
private String summary;//专栏简介
private java.util.Date createTime;//创建日期
private java.util.Date updateTime;//更新日期
private String state;//状态
查询成功
删除成功
我的id是用雪花算法生成的,所以没有用到@GeneratedValue
如果你想要数据库自己生成id的话就要在ID字段上加一下
引用资料:
https://blog.csdn.net/u010138825/article/details/83095026