为什么 Hibernate 不创建多对多连接表?
Why is Hibernate not creating many-to-many join tables?
我正在尝试让 Hibernate 创建多对多关系连接 table。实体 table 创建得很好,但连接 table 不会显示。一些来源手动创建连接 table,其他来源(如 Youtube 教程)解释了 Hibernate 如何自动创建它们。
这是我的第一个实体 table:
package com.presents;
import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.Set;
@Entity
@Table(name = "articles")
public class Article implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "link")
private String url;
@Column(name = "likes")
private int likes;
@Column(name = "clicks")
private int clicks;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "category_article",
joinColumns = {
@JoinColumn(name = "article_id", referencedColumnName = "id")
},
inverseJoinColumns = {
@JoinColumn(name = "category_id", referencedColumnName = "id")
}
)
public Set<Categories> categories = new HashSet<>();;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getLikes() {
return likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
public int getClicks() {
return clicks;
}
public void setClicks(int clicks) {
this.clicks = clicks;
}
public Set<Categories> getCategories() {
return cats;
}
public void setCategories(Set<Categories> categories) {
this.cats = categories;
}
}
这是我的第二个实体 table:
包 com.presents;
import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "category")
public class Categories implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "category")
private String category;
@ManyToMany(mappedBy = "categories")
public Set<Article> articles = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setCategory(String category) {
this.category = category;
}
public String getCategory() {
return category;
}
public void setArticles(Set<Article> articles) {
this.articles = articles;
}
public Set<Article> getArticles() {
return articles;
}
}
想法是任何文章都可以属于多个类别,但不止一个类别可以适用于任何文章。
我正在使用 SQLite3 数据库,但我也尝试使用 MySQL 数据库,但均无济于事。 Hibernate 似乎以某种方式完全避免了多对多注释。当我 运行 代码并且似乎完全避免它时,它不会抱怨它。同样,table 的另一个创建得非常漂亮,我没有摸索任何 SQL 命令。
为什么 Hibernate 拒绝创建连接 table,我该如何解决?
这是 Hibernate 的输出:
INFO: HHH000412: Hibernate ORM core version 5.6.2.Final
Dez. 18, 2021 8:41:14 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [org.sqlite.JDBC] at URL [jdbc:sqlite:presents.db]
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {}
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Dez. 18, 2021 8:41:15 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.SQLiteDialect
Hibernate: drop table if exists articles
Hibernate: drop table if exists category
Hibernate: drop table if exists hibernate_sequence
Hibernate: create table articles (id integer not null, name varchar, link varchar, likes integer, clicks integer, primary key (id))
Hibernate: create table category (id integer not null, category varchar, primary key (id))
Hibernate: create table hibernate_sequence (next_val bigint)
Hibernate: insert into hibernate_sequence values ( 1 )
Dez. 18, 2021 8:41:16 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@334ebcaa] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Dez. 18, 2021 8:41:16 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@107bfcb2] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Dez. 18, 2021 8:41:16 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: select categories0_.id as id1_1_, categories0_.category as category2_1_ from category categories0_
您需要获取一篇文章,然后添加分类并保存。例如:
Categories category = categoryRepository.getById(100001);
article.getCategories().add(category);
articlesRepository.save(article);
productRepository.findAll();
这将向 category_article table 添加一个新条目。
我自己发现了错误。当我应该使用 Hibernate XML 映射时,我使用了 JPA 注释。在删除每个注释并在 XML 映射文件中创建必要的行后,table 出现了。
我正在尝试让 Hibernate 创建多对多关系连接 table。实体 table 创建得很好,但连接 table 不会显示。一些来源手动创建连接 table,其他来源(如 Youtube 教程)解释了 Hibernate 如何自动创建它们。
这是我的第一个实体 table:
package com.presents;
import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.Set;
@Entity
@Table(name = "articles")
public class Article implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "link")
private String url;
@Column(name = "likes")
private int likes;
@Column(name = "clicks")
private int clicks;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "category_article",
joinColumns = {
@JoinColumn(name = "article_id", referencedColumnName = "id")
},
inverseJoinColumns = {
@JoinColumn(name = "category_id", referencedColumnName = "id")
}
)
public Set<Categories> categories = new HashSet<>();;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getLikes() {
return likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
public int getClicks() {
return clicks;
}
public void setClicks(int clicks) {
this.clicks = clicks;
}
public Set<Categories> getCategories() {
return cats;
}
public void setCategories(Set<Categories> categories) {
this.cats = categories;
}
}
这是我的第二个实体 table:
包 com.presents;
import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "category")
public class Categories implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "category")
private String category;
@ManyToMany(mappedBy = "categories")
public Set<Article> articles = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setCategory(String category) {
this.category = category;
}
public String getCategory() {
return category;
}
public void setArticles(Set<Article> articles) {
this.articles = articles;
}
public Set<Article> getArticles() {
return articles;
}
}
想法是任何文章都可以属于多个类别,但不止一个类别可以适用于任何文章。
我正在使用 SQLite3 数据库,但我也尝试使用 MySQL 数据库,但均无济于事。 Hibernate 似乎以某种方式完全避免了多对多注释。当我 运行 代码并且似乎完全避免它时,它不会抱怨它。同样,table 的另一个创建得非常漂亮,我没有摸索任何 SQL 命令。 为什么 Hibernate 拒绝创建连接 table,我该如何解决?
这是 Hibernate 的输出:
INFO: HHH000412: Hibernate ORM core version 5.6.2.Final
Dez. 18, 2021 8:41:14 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [org.sqlite.JDBC] at URL [jdbc:sqlite:presents.db]
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {}
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Dez. 18, 2021 8:41:15 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Dez. 18, 2021 8:41:15 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.SQLiteDialect
Hibernate: drop table if exists articles
Hibernate: drop table if exists category
Hibernate: drop table if exists hibernate_sequence
Hibernate: create table articles (id integer not null, name varchar, link varchar, likes integer, clicks integer, primary key (id))
Hibernate: create table category (id integer not null, category varchar, primary key (id))
Hibernate: create table hibernate_sequence (next_val bigint)
Hibernate: insert into hibernate_sequence values ( 1 )
Dez. 18, 2021 8:41:16 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@334ebcaa] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Dez. 18, 2021 8:41:16 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@107bfcb2] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Dez. 18, 2021 8:41:16 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into articles (name, link, likes, clicks, id) values (?, ?, ?, ?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: insert into category (category, id) values (?, ?)
Hibernate: select categories0_.id as id1_1_, categories0_.category as category2_1_ from category categories0_
您需要获取一篇文章,然后添加分类并保存。例如:
Categories category = categoryRepository.getById(100001);
article.getCategories().add(category);
articlesRepository.save(article);
productRepository.findAll();
这将向 category_article table 添加一个新条目。
我自己发现了错误。当我应该使用 Hibernate XML 映射时,我使用了 JPA 注释。在删除每个注释并在 XML 映射文件中创建必要的行后,table 出现了。