1

I am new to Jpa and jpql, I need to generate dropdown menu from a query. In codeigniter it was easy. I'd just do query inside a query in recursive function.

Here is the sample

function main_menu($base_id, $id=NULL, $class=NULL, $selected=NULL )
{
        $this->db->select('id, url, parent_id,title,');
        $this->db->where('parent_id',$base_id);
        $this->db->order_by('sort_order','asc');
        $query = $this->db->get('tbl_menu');

        if($query->num_rows()>0)
        {   
            if($this->level == 0) 
                echo "<ul class='".$class."' id='".$id."' >";
            else 
                echo '<ul>';

            foreach ($query->result() as $row)
            {       
                    $this->db->select('id,url,parent_id,title');
                    $this->db->where('parent_id',$row->id);
                    $this->db->order_by('sort_order','asc');

                    $query = $this->db->get('tbl_menu');

                    if($this->level == 0) 
                       echo "<li class='".$selected."'> ";  
                    else 
                       echo '<li>';

                    echo "<a href='".$row->url."'>".$row->title."</a>"; 

                    if($query->num_rows() > 0)
                    {               
                            $this->Common->main_menu($row->id , $id=NULL, $class=NULL, $selected=NULL  );   
                            $this->level++;     
                    }

                    echo '</li>';
                }

                echo '</ul>';
        }
    }

but now I am learning spring mvc and I need to generate dropdown menu. Here is what I have tried and it does not work at all.

This is my Dao method

@Repository
public class CategoryDao {

@PersistenceContext
private EntityManager entityManager;

private String menu = "";
public String GenerateCategoryMenu(Long parid){

    String query= "Select o FROM Categories As o WHERE o.parent_id = :parid";
    TypedQuery<Categories> q = entityManager.createQuery(query, Categories.class);
    q.setParameter("parid", parid);
    List<Categories> results = q.getResultList();
    if (!results.isEmpty()) {

        // writting on menu string
        this.menu = this.menu+"<ul>";
        Iterator<Categories> itr = results.iterator();

        while(itr.hasNext()) {
            Categories cat = itr.next();

            String query = "Select o FROM Categories As o WHERE o.parent_id = :par";
            TypedQuery<Categories> qb = entityManager.createQuery(query, Categories.class);
            qb.setParameter("par", cat.getId());
            List<Categories> childs = q.getResultList();

            // Concat String
            this.menu = this.menu+"<li><a href='http://localhost:8080/librarymanagementsystem/category/show/"+cat.getId()+"'>"+cat.getTitle()+"</a>";


            if(!childs.isEmpty()){
                GenerateCategoryMenu(cat.getId());
            }

            this.menu = this.menu+"</li>";

        }
        this.menu = this.menu+"</ul>";

    }

    return this.menu;
}

I get session is closed error

org.hibernate.SessionException: Session is closed!

Here is my category code

@Entity
@Table(name = "categories")
public class Categories {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

private Long parent_id;

private String title;

private String url_title;

private String description;

private String created;

private String updated;

/* 
 * @ At the time of Creating new user
 * Auto persist created date
 * Auto persist updated for first time
 */
@PrePersist
protected void onCreate (){

    // Date conversion to string
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd h:mm:s");
    sdf.setLenient(false);
    String now = sdf.format(date);

    created = now;
    updated = now;


}


/*
 *  Respective Getter and Setter Methods
 *  
 */
public Long getId() {
    return id;
}public void setId(Long id) {
    this.id = id;
}

public Long getParent_id() {
    return parent_id;
}public void setParent_id(Long parent_id) {
    this.parent_id = parent_id;
}

public String getTitle() {
    return title;
}public void setTitle(String title) {
    this.title = title;
}

public String getUrl_title() {
    return url_title;
}public void setUrl_title(String url_title) {
    this.url_title = url_title;
}

public String getCreated() {
    return created;
}public void setCreated(String created) {
    this.created = created;
}

public String getUpdated() {
    return updated;
}public void setUpdated(String updated) {
    this.updated = updated;
}

public String getDescription() {
    return description;
}public void setDescription(String description) {
    this.description = description;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Categories other = (Categories) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

The problem is: I could not achieve what I needed with the typed query, somebody please guide me how to achieve this in jpql/Jpa. I am using spring mvc, hibernate and mysql right now.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
nikesh adhikari
  • 113
  • 2
  • 11
  • I think that your entityManager/session is being closed at some point before you launch your getResultList. It's not clear in your code how you inject your entityManager. Check this out. – RubioRic Jun 08 '16 at 10:14
  • Yes, if Categories is an Entity, you can execute those queries. Could you copy your Categories' code? I think that you don't need to write explicitily the query in the while-loop and the recursive call, let Hibernate do it for you by traversing the first recovered object relations. – RubioRic Jun 08 '16 at 11:27
  • On the other hand, I'm no Spring expert, I need more time to study what happens with the injected entityManager. Maybe some other can help you on that subject. – RubioRic Jun 08 '16 at 11:29
  • I just added my categories code would you please check it. – nikesh adhikari Jun 08 '16 at 11:41
  • You have not defined the relation between a Category and his Category children. Here is an example of how you can do it http://stackoverflow.com/questions/3393515/jpa-how-to-have-one-to-many-relation-of-the-same-entity-type – RubioRic Jun 08 '16 at 11:46
  • 1
    i just solved it, just by adding @transactional at my generateCategoryMenu(long id). – nikesh adhikari Jun 08 '16 at 11:49
  • some one was explaining that transactional annotation wont close session until the complete method is executed. and it worked like a charm. thanks for your effort @RubioRic – nikesh adhikari Jun 08 '16 at 11:51
  • Congrats. But do not forget to look into JPA/Hibernate relation mapping when you got time. :-) – RubioRic Jun 08 '16 at 11:51
  • I am looking at what you just suggested right now. Can you provide me some links ? that would be a great help. thank you @RubioRic – nikesh adhikari Jun 08 '16 at 12:02
  • I've already provided you a link that explains how to map a self join relation like yours. You can learn more about mapping relations with JPA/Hibernate in these sites https://howtoprogramwithjava.com/hibernate-manytoone-unidirectional-tutorial/ http://viralpatel.net/blogs/hibernate-self-join-annotations-one-to-many-mapping/ There are other links in those pages that will show you how to map different relations. If you got trouble querying the data, ask here and me or someone else will help you. :-) – RubioRic Jun 08 '16 at 13:32

0 Answers0