与嵌入式键的多对多关系是在主键中插入空值
Many to Many relation with embedded key is inserting null in primary key
在中间 table 中插入记录时遇到问题。
Post 和标签 table 正在使用中间 table post_tag;
共享多对多关系
Post table: id (pk), post, created_by, created_on, modified_by, modified_on
标签 table: id (pk), 标签, created_by, created_on, modified_by, modified_on
Post_Tag table: post_id, tag_id (pk post_id and tag_id), created_by, created_on、modified_by、modified_on
实体:
// ID class
@Embeddable @Data @NoArgsConstructor @AllArgsConstructor
public class PostTagId
implements Serializable {
@Column(name = "post_id")
private Long postId;
@Column(name = "tag_id")
private Long tagId;
}
@Entity
@Table(name = "post_tag")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = false)
public class PostTag extends Auditable<String> {
@EmbeddedId
private PostTagId id;
@ManyToOne
@MapsId("postId")
@JoinColumn(name="post_id")
private Post post;
@ManyToOne
@MapsId("tagId")
@JoinColumn(name="tag_id")
private Tag tag;
public PostTag(Post post, Tag tag) {
this.post = post;
this.tag = tag;
this.id = new PostTagId(post.getId(), tag.getId());
}
}
使用springboot(AuditingEntityListener) 添加审计列。 Post 和 Tag 实体有点像 -
///////////Tag
@Data
@EqualsAndHashCode(callSuper = false, exclude = {"postTags"})
@ToString( exclude = {"postTags"})
@Entity
@Table(name = "tag")
@EntityListeners(AuditingEntityListener.class)
public class Tag extends Auditable<String> {
@Id
private Long id;
@Column(name = "tag")
private String tag;
@OneToMany(mappedBy = "tag", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<PostTag> postTags;
}
//////////////POST
@Data
@EqualsAndHashCode(callSuper = false, exclude = {"postTags"})
@ToString( exclude = {"postTags"})
@Entity
@Table(name = "post")
@EntityListeners(AuditingEntityListener.class)
public class Post extends Auditable<String> {
@Id
private Long id;
@Column(name = "post")
private String post;
@OneToMany(mappedBy = "post", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<PostTag> postTags;
public void addTag(Tag tag) {
PostTag postTag = new PostTag(this, tag);
if (postTags == null) {
postTags = new HashSet<>();
}
postTags.add(postTag);
tag.getPostTags().add(postTag);
}
}
使用 addTag() 方法插入标签的代码片段 -
public Post create(Post post) {
// DefaultTag is some default tag getting from repository
post.addTag(DefaultTag)
return postRepo.save(post);
}
Insert in post_tag 正在尝试插入 null post_id。
Hibernate:
insert
into
post_tag
(created_by, created_on, modified_by, modified_on, post_id, tag_id)
values
(?, ?, ?, ?, ?, ?) [0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper SQL Error: 0, SQLState:
23502 [0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper ERROR: null
value in column "post_id" violates not-null constraint Detail:
Failing row contains (null, 100, anonymousUser, anonymousUser,
2020-07-06 15:22:19.227-06, 2020-07-06 15:22:19.227-06).
删除了@EmbededId 并在Post标记class 中使用了@Id。这种方式不需要在构造函数中创建 embededId,hibernate 会处理 id 创建。变化看起来像这样 -
@Entity
@Table(name = "post_tag")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = false)
public class PostTag extends Auditable<String> implements Serializable {
@ManyToOne
@Id
@JoinColumn(name="post_id")
private Post post;
@ManyToOne
@Id
@JoinColumn(name="tag_id")
private Tag tag;
}
由于PostTag(Post, Tag)构造函数被移除,addTag(Tag tag)方法需要在[=19=中进行重构]实体。
public void addTag(Tag tag) {
PostTag postTag = new PostTag();
postTag.setPost(this);
postTag.setTag(tag);
if (postTags == null) {
postTags = new HashSet<>();
}
postTags.add(postTag);
tag.getPostTags().add(postTag);
}
在中间 table 中插入记录时遇到问题。 Post 和标签 table 正在使用中间 table post_tag;
共享多对多关系Post table: id (pk), post, created_by, created_on, modified_by, modified_on
标签 table: id (pk), 标签, created_by, created_on, modified_by, modified_on
Post_Tag table: post_id, tag_id (pk post_id and tag_id), created_by, created_on、modified_by、modified_on
实体:
// ID class
@Embeddable @Data @NoArgsConstructor @AllArgsConstructor
public class PostTagId
implements Serializable {
@Column(name = "post_id")
private Long postId;
@Column(name = "tag_id")
private Long tagId;
}
@Entity
@Table(name = "post_tag")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = false)
public class PostTag extends Auditable<String> {
@EmbeddedId
private PostTagId id;
@ManyToOne
@MapsId("postId")
@JoinColumn(name="post_id")
private Post post;
@ManyToOne
@MapsId("tagId")
@JoinColumn(name="tag_id")
private Tag tag;
public PostTag(Post post, Tag tag) {
this.post = post;
this.tag = tag;
this.id = new PostTagId(post.getId(), tag.getId());
}
}
使用springboot(AuditingEntityListener) 添加审计列。 Post 和 Tag 实体有点像 -
///////////Tag
@Data
@EqualsAndHashCode(callSuper = false, exclude = {"postTags"})
@ToString( exclude = {"postTags"})
@Entity
@Table(name = "tag")
@EntityListeners(AuditingEntityListener.class)
public class Tag extends Auditable<String> {
@Id
private Long id;
@Column(name = "tag")
private String tag;
@OneToMany(mappedBy = "tag", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<PostTag> postTags;
}
//////////////POST
@Data
@EqualsAndHashCode(callSuper = false, exclude = {"postTags"})
@ToString( exclude = {"postTags"})
@Entity
@Table(name = "post")
@EntityListeners(AuditingEntityListener.class)
public class Post extends Auditable<String> {
@Id
private Long id;
@Column(name = "post")
private String post;
@OneToMany(mappedBy = "post", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<PostTag> postTags;
public void addTag(Tag tag) {
PostTag postTag = new PostTag(this, tag);
if (postTags == null) {
postTags = new HashSet<>();
}
postTags.add(postTag);
tag.getPostTags().add(postTag);
}
}
使用 addTag() 方法插入标签的代码片段 -
public Post create(Post post) {
// DefaultTag is some default tag getting from repository
post.addTag(DefaultTag)
return postRepo.save(post);
}
Insert in post_tag 正在尝试插入 null post_id。
Hibernate:
insert
into
post_tag
(created_by, created_on, modified_by, modified_on, post_id, tag_id)
values
(?, ?, ?, ?, ?, ?) [0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper SQL Error: 0, SQLState:
23502 [0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper ERROR: null
value in column "post_id" violates not-null constraint Detail:
Failing row contains (null, 100, anonymousUser, anonymousUser,
2020-07-06 15:22:19.227-06, 2020-07-06 15:22:19.227-06).
删除了@EmbededId 并在Post标记class 中使用了@Id。这种方式不需要在构造函数中创建 embededId,hibernate 会处理 id 创建。变化看起来像这样 -
@Entity
@Table(name = "post_tag")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = false)
public class PostTag extends Auditable<String> implements Serializable {
@ManyToOne
@Id
@JoinColumn(name="post_id")
private Post post;
@ManyToOne
@Id
@JoinColumn(name="tag_id")
private Tag tag;
}
由于PostTag(Post, Tag)构造函数被移除,addTag(Tag tag)方法需要在[=19=中进行重构]实体。
public void addTag(Tag tag) {
PostTag postTag = new PostTag();
postTag.setPost(this);
postTag.setTag(tag);
if (postTags == null) {
postTags = new HashSet<>();
}
postTags.add(postTag);
tag.getPostTags().add(postTag);
}