场景是我有一个表示文件夹结构中的节点的类,它具有ID,名称和指向其父节点的链接。我试图写一些删除所有文件夹的代码,但查询" DELETE FROM Folder"如果文件夹没有以完全正确的顺序删除,则由于完整性限制而不再有效 - 即如果文件夹中有一个引用它的子文件夹,则无法删除该文件夹。
因此需要首先删除没有子节点的文件夹,然后可以删除随后没有子节点的文件夹,反之亦然,直到可以删除根文件夹。
我已尝试为此效果编写循环,但我在查询中苦苦挣扎,代码如下:
int rowsAffected = -1;
while(rowsAffected != 0) {
query = entityManager.createQuery(
"DELETE FROM MessageFolder mfparent"
+ "WHERE NOT EXISTS ("
+ "FROM MessageFolder mfchild"
+ "WHERE mfchild.parentId = mfparent.id"
+ ") ");
rowsAffected = query.executeUpdate();
}
我从中得到的错误是:
10:56:00,988 INFO [stdout](默认任务-9)休眠:从PT_MESSAGE删除 10:56:01,004 ERROR [org.hibernate.hql.internal.ast.ErrorCounter](默认任务-9)第1:72行:unexpec 特德令牌:不 10:56:01,004 ERROR [org.hibernate.hql.internal.ast.ErrorCounter](默认任务-9)第1:72行:unexpec 特德令牌:不:第1:72行:意外的令牌:不是 在org.hibernate.hql.internal.antlr.HqlBaseParser.deleteStatement(HqlBaseParser.java:296)[h ibernate芯-4.3.1.Final.jar:4.3.1.Final]
我不太了解" NOT EXISTS"似乎是有效的JPA规范的一部分。我究竟做错了什么?还要注意我的持久性提供程序是Hibernate,所以如果我能用JPA或Hibernate以更好的方式做到这一点,那么这也是一种选择。
作为参考,MessageFolder类在这里:
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="PT_MESSAGE_FOLDER")
public class MessageFolder {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String name;
@OneToMany(mappedBy="messageFolder", targetEntity=Message.class,
cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<Message> messages;
@OneToOne
@JoinColumn(name="parentId", referencedColumnName="id")
private MessageFolder parentFolder;
public MessageFolder() {
messages = new ArrayList<>();
}
//getters.. setters...
}
答案 0 :(得分:2)
您的主要问题是字符串连接,例如:
mfparent"
+ "WHERE
由于缺少空格键字符,会产生无效语句
mfparentWHERE
我的建议是停止在JPQL中拆分String,因为它带来的弊大于利。
答案 1 :(得分:1)
我认为您可以使用 子句中的实现此目的:
query = entityManager.createQuery(
"DELETE FROM MessageFolder "
+ "WHERE id NOT in ("
+ "SELECT distinct parentFolder.id FROM MessageFolder"
+ ") ");
rowsAffected = query.executeUpdate();