我正在尝试删除我的webapp上的一些数据,我有一个名为 post_it 的表和另一个名为 check_list 的表。问题是,hibernate生成一个组合两个名称的查询,例如,它们只有一个ManyToOne关系:
Hibernate:
delete
from
post_it_check_list
where
(
post_it_id
) in (
select
id
from
post_it
where
id=?
)
然后抛出一个SQLException ... Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'pinleaf.post_it_check_list' doesn't exist
。
我正在使用Spring-Data JPA,所以我的查询是:
@Query(value = "delete from PostIt as p where p.id=:postItId")
这些是涉及的映射实体:
@Entity
@Table(name = "check_list")
public class CheckList extends BaseEntity {
private PostIt postIt;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name = "post_it", referencedColumnName = "id", nullable = true)
public PostIt getPostIt() {
return postIt;
}
public void setPostIt(PostIt postIt) {
this.postIt = postIt;
}
}
和
@Entity
@Table(name = "post_it")
public class PostIt extends BaseEntity {
private String title;
private String content;
private Timestamp createdAt;
private Timestamp dueDate;
private Integer urgency;
private boolean archived;
private Board board;
private Collection<CheckList> checkLists;
private Collection<Tag> tags;
@Column(name = "title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Column(name = "content")
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@Column(name = "created_at")
public Timestamp getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Timestamp createdAt) {
this.createdAt = now(createdAt);
}
private Timestamp now(Timestamp incommingTimestamp) {
return incommingTimestamp == null ? Timestamp.valueOf(java.time.LocalDateTime.now()) : incommingTimestamp;
}
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@Column(name = "due_date")
public Timestamp getDueDate() {
return dueDate;
}
public void setDueDate(Timestamp dueDate) {
this.dueDate = dueDate;
}
@Column(name = "urgency")
public Integer getUrgency() {
return urgency;
}
public void setUrgency(Integer urgency) {
this.urgency = urgency;
}
@Column(name = "archived")
public boolean isArchived() {
return archived;
}
public void setArchived(boolean archived) {
this.archived = archived;
}
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name = "board", referencedColumnName = "id", nullable = false)
public Board getBoard() {
return board;
}
public void setBoard(Board board) {
this.board = board;
}
@OneToMany(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
public Collection<CheckList> getCheckLists() {
return checkLists;
}
public void setCheckLists(Collection<CheckList> checkLists) {
this.checkLists = checkLists;
}
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name = "post_it_tags",
joinColumns = @JoinColumn(name = "post_it", nullable = true),
inverseJoinColumns = @JoinColumn(name = "tag", nullable = true))
public Collection<Tag> getTags() {
return tags;
}
public void setTags(Collection<Tag> tags) {
this.tags = tags;
}
}
答案 0 :(得分:0)
两个实体之间有两种不同的单向关联。一个是从CheckList到PostIt的ManyToOne:
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name = "post_it", referencedColumnName = "id", nullable = true)
public PostIt getPostIt() {
return postIt;
}
,第二个是从PostIt到CheckList的OneToMany,与第一个没关系:
@OneToMany(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
public Collection<CheckList> getCheckLists() {
return checkLists;
}
由于您没有指定如何映射此单向OneToMany,因此Hibernate采用默认设置,即在两个表之间使用连接表。
如果您打算使用单个双向关联,则必须使用mappedBy
属性将第二个关联标记为第一个关联:
@OneToMany(mappedBy = "postIt", cascade = {CascadeType.MERGE, CascadeType.REMOVE})
public Collection<CheckList> getCheckLists() {
return checkLists;
}
请注意,使用此删除查询会让您的生活变得困难。你可以简单地使用
em.remove(em.getReference(PostIt.class, id));