 <p>I don't know why you want to keep the unidirectional relation here, because making it bidirectional would make your life much easier.</p> <p>First, <code>CascadeType.ALL</code> on the parent mapping in your example means that if you delete the subfolder, its parent will be deleted also. And this will propagate all the way up to the root folder which is probably not what you want.</p> <p>With bidirectonal mapping it would look like this</p> <pre><code>@ManyToOne @JoinColumn(name = "parent_folder_id") protected Folder parentFolder; @OneToMany(mappedBy = "parentFolder", cascade = {CascadeType.ALL}) protected Set&lt;Folder&gt; children; </code></pre> <p>Without this, you should implement the cascade yourself. This will get complicated for more complicated folder structures (when checking the children of a folder before deletion, you'll have to check grandchildren... and so on). It could be done with one recursive method, but definitely a lot more work than with bidirectional relation.</p> <pre><code>/* pseudo code */ public void deleteFolder(Folder f) { Set&lt;Folder&gt; children = session.createQuery("from Folder where parentFolder.id = :parentId").setParameter("parentId", f.getId()).list(); for each child { deleteFolder(child) } session.delete(f) } </code></pre>