项目场景:
项目语言:Java,框架:Spring Boot,书籍:Spring 实战(第5版)
在学习Spring 实战(第5版)
该书使用h2数据库进行教学,中途嫌麻烦想换成mysql进行余下的学习,切换中发生错误
问题描述
使用@ManyToMany注解的时候报错
报错信息
2023-04-23 23:24:54.131 ERROR 19164 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement] with root cause
java.sql.SQLSyntaxErrorException: Table 'taco_cloud.Taco_Ingredient' doesn't exist
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.21.jar:8.0.21]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.21.jar:8.0.21]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.21.jar:8.0.21]
源代码
package tacos.domain;
import lombok.Data;
import lombok.NonNull;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
@Data
@Entity
public class Taco {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
@Size(min = 5, message = "名字的长度必须大于5个字符")
private String name;
@Size(min = 1, message = "你必须得选择一项食材")
@ManyToMany(targetEntity = Ingredient.class)
private List<Ingredient> ingredients;
private Date createdAt;
@PrePersist
private void createAt() {
this.createdAt = new Date();
}
public Taco() {
}
}
原因分析:
报错显示
Table 'taco_cloud.Taco_Ingredient' doesn't exist
说明是表不存在的问题,可以选择建立对应的表,但是这样太局限
例如:Handler
发送消息有两种方式,分别是 Handler.obtainMessage()
和 Handler.sendMessage()
,其中 obtainMessage
方式当数据量过大时,由于 MessageQuene
大小也有限,所以当 message
处理不及时时,会造成先传的数据被覆盖,进而导致数据丢失。
解决方案:
所以选择使用
@JoinTable
注解为@ManyToMany
建立表关系映射
@ManyToMany(targetEntity = Ingredient.class)
@JoinTable(
name = "Taco_Ingredients",
joinColumns = {@JoinColumn(name = "taco", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "ingredient", referencedColumnName = "id")}
)
private List<Ingredient> ingredients;
映射的注解说明
@ManyToMany
- 作用:用于映射多对多关系
- 属性:
- cascade:配置级联操作。
- fetch:配置是否采用延迟加载。
- targetEntity:配置目标的实体类。
@JoinTable
- 作用:针对中间表的配置
- 属性:
- name:配置中间表的名称
- joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
- inverseJoinColumn:中间表的外键字段关联对方表的主键字段