code: @SuppressWarnings("unchecked")
      public E cloneAndPersistTreeNode(E node) throws Exception {
  
          if (node == null) {
              throw new Exception("Node to clone must not be null.");
          }
  
          // unproxy the node to be sure that everything (on top level) is loaded eagerly
          // before we continue to care about possible child notes and persistance
          node = dao.unproxy(node);
  
          if (node instanceof TreeFolder) {
              List<E> children = (List<E>) ((TreeFolder) node).getChildren();
              List<E> clonedChildren = new ArrayList<>();
              for (E childNode : children) {
                  // recursive call for all children
                  clonedChildren.add(cloneAndPersistTreeNode(childNode));
              }
              ((TreeFolder) node).setChildren((List<TreeNode>) children);
          }
  
          // detach the clone from the hibernate session to persist it as a new instance in the next step
          dao.evict(node);
  
          // set id to null to persist a new instance afterwards
          IdHelper.setIdOnPersistentObject(node, null);
  
          // persist the same object as a new entry in database
          dao.saveOrUpdate(node);
  
          return node;
      }
docs: This unproxies and eagerly fetches the whole node/tree and detaches it
  from the hibernate session before persisting a new "clone" instance in the database.
  In case of a TreeFolder, each child node will also be re-persisted (as a new database entry).
  
  @param node
  @return
  @throws IllegalAccessException
  @throws NoSuchFieldException