我正在使用Spring-Boot
,Hibernate
和MariaDB
。我有一个book
实体和一个author
实体,并通过双向book_authors
关联将它们映射到@manytomany
表。似乎已使用适当的外键约束创建了联接表,但是,当我向其各自的表中添加作者然后再添加书籍时,并不会填充联接表。我将ddl-auto
设置为validate
,所以该表没有被覆盖。我可以看到由hibernate生成的sql join语句,当我手动运行它时,它会拉正确的列,但我从未看到insert语句。我也尝试了CascadeTypes的几种不同组合,但是不确定为什么休眠不保留数据。
最初,每个实体都由单独的微服务bookmsvc
和authormsvc
管理,但是在遇到manytomany
关联问题后,我将两个实体都复制到了两个微服务中。我不确定这是否必要或最佳做法。我的工作流程为:
在这一点上,我希望可以填充联接表。我确定我有一个基本的误解,但是我不确定这是什么。我读过最好使用两个onetomany / manytoone关联,但是我不确定这是否准确反映了这种关系?有更好的方法吗?
如果没有,我如何进入休眠状态以填充联接表?
作者
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull @Column(name = "author_name")
private String authorName;
@ManyToMany( mappedBy = "authors",
fetch = FetchType.LAZY,
cascade = { CascadeType.PERSIST, CascadeType.MERGE })
public List<Book> books = new ArrayList<>();
public Author() {}
public Long getId() {
return id;
}
public String getAuthorName() {
return authorName;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.authorName = name;
}
}
图书
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull @Column(name = "title")
private String title;
@NotNull @Column(name = "pub_id")
private Long pubId;
@NotNull @Column(name = "auth_id")
private Long authId;
@ManyToMany(
fetch = FetchType.LAZY,
cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(name = "book_authors",
joinColumns = {
@JoinColumn(
name = "book_id",
referencedColumnName = "id"
)
},
inverseJoinColumns = {
@JoinColumn(
name = "auth_id",
referencedColumnName = "id"
)
})
public List<Author> authors = new ArrayList<>();
public Book() {}
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public Long getPubId() {
return pubId;
}
public Long getAuthId() {
return authId;
}
public void setId(Long id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setPubId(Long pubId) {
this.pubId = pubId;
}
public void setAuthId(Long authId) {
this.authId = authId;
}
}
由休眠生成的SQL
create table author (id bigint not null auto_increment, author_name varchar(255) not null, primary key (id)) engine=MyISAM
create table book (id bigint not null auto_increment, auth_id bigint not null, pub_id bigint not null, title varchar(255) not null, primary key (id)) engine=MyISAM
create table book_authors (book_id bigint not null, auth_id bigint not null) engine=MyISAM
alter table book_authors add constraint FKo21n38yco1hp4gvkb1xobm5vx foreign key (auth_id) references author (id)
alter table book_authors add constraint FK9s79v70m4fxo4c0qigpn5daf8 foreign key (book_id) references book (id)
select authors0_.book_id as book_id1_2_0_, authors0_.auth_id as auth_id2_2_0_, author1_.id as id1_0_1_, author1_.author_name as author_n2_0_1_ from book_authors authors0_ inner join author author1_ on authors0_.auth_id=author1_.id where authors0_.book_id=?
book_authors表
MariaDB [lms]> describe book_authors;
+---------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| book_id | bigint(20) | NO | MUL | NULL | |
| auth_id | bigint(20) | NO | PRI | NULL | |
+---------+------------+------+-----+---------+-------+
2 rows in set (0.002 sec)
MariaDB [lms]> select * from book_authors;
Empty set (0.001 sec)