bjzt 的个人博客 bjzt 的个人博客

记录精彩的程序人生

目录
spring data jpa 的自动建表、映射关系、和级联保存
/  

spring data jpa 的自动建表、映射关系、和级联保存

这两天我在想做一个东西,需要将文章保存的同时,将文章相关的表也一起保存,想用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;//状态

这时类的关系就配置好了
表也正常创建出来了
表.png
也能添加对象
test.png
但是查询出了问题

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]->

解决json的无限循环依赖

我找了一堆资料,后来在一篇博客 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;//状态

查询成功
select.png

删除成功
select.png

最后说一下

我的id是用雪花算法生成的,所以没有用到@GeneratedValue如果你想要数据库自己生成id的话就要在ID字段上加一下

引用资料:
https://blog.csdn.net/u010138825/article/details/83095026