com.apress.progwt.server.dao.hibernate.SchoolDAOHibernateImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.apress.progwt.server.dao.hibernate.SchoolDAOHibernateImpl.java

Source

/*
 * Copyright 2008 Jeff Dwyer
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.apress.progwt.server.dao.hibernate;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.apress.progwt.client.domain.Application;
import com.apress.progwt.client.domain.ForumPost;
import com.apress.progwt.client.domain.Loadable;
import com.apress.progwt.client.domain.ProcessType;
import com.apress.progwt.client.domain.RatingType;
import com.apress.progwt.client.domain.School;
import com.apress.progwt.client.domain.SchoolForumPost;
import com.apress.progwt.client.domain.User;
import com.apress.progwt.client.domain.UserForumPost;
import com.apress.progwt.client.domain.dto.PostsList;
import com.apress.progwt.server.dao.SchoolDAO;

public class SchoolDAOHibernateImpl extends HibernateDaoSupport implements SchoolDAO {

    private int autoCompleteMax = 7;

    private static final Logger log = Logger.getLogger(SchoolDAOHibernateImpl.class);

    public Loadable get(Class<? extends Loadable> loadable, Long id) {
        return (Loadable) getHibernateTemplate().get(loadable, id);
    }

    public List<School> getAllSchools(int start, int max) {
        DetachedCriteria crit = DetachedCriteria.forClass(School.class).addOrder(Order.desc("popularityCounter"));

        // .add(
        // Expression.and(Expression.gt("id", 890l),
        // Expression.eq("latitude", -1d)));
        List<School> list = getHibernateTemplate().findByCriteria(crit, start, max);
        return list;
    }

    public List<ProcessType> getDefaultProcessTypes() {
        DetachedCriteria crit = DetachedCriteria.forClass(ProcessType.class)
                .add(Expression.eq("useByDefault", true)).addOrder(Order.asc("id"));

        return getHibernateTemplate().findByCriteria(crit);
    }

    public List<RatingType> getDefaultRatingTypes() {
        DetachedCriteria crit = DetachedCriteria.forClass(RatingType.class).add(Expression.eq("useByDefault", true))
                .addOrder(Order.asc("id"));

        return getHibernateTemplate().findByCriteria(crit);
    }

    public ProcessType getProcessForName(String string) {
        DetachedCriteria crit = DetachedCriteria.forClass(ProcessType.class).add(Expression.eq("name", string));

        return (ProcessType) DataAccessUtils.uniqueResult(getHibernateTemplate().findByCriteria(crit));
    }

    public School getSchoolFromName(String name) {
        return (School) DataAccessUtils.uniqueResult(getHibernateTemplate().find("from School where name=?", name));
    }

    public List<School> getSchoolsMatching(String match) {
        return getSchoolsMatching(match, 0, autoCompleteMax, MatchMode.ANYWHERE);
    }

    /**
     * use start matchmode
     */
    public List<School> getSchoolsMatching(String match, int start, int max) {
        return getSchoolsMatching(match, start, max, MatchMode.START);
    }

    public List<School> getSchoolsMatching(String match, int start, int max, MatchMode matchMode) {

        DetachedCriteria crit = DetachedCriteria.forClass(School.class)
                .add(Expression.ilike("name", match, matchMode)).addOrder(Order.asc("name"));

        List<School> list = getHibernateTemplate().findByCriteria(crit, start, max);

        return list;
    }

    public List<ProcessType> matchProcessType(String queryString) {
        DetachedCriteria crit = DetachedCriteria.forClass(ProcessType.class)
                .add(Expression.ilike("name", queryString, MatchMode.ANYWHERE)).addOrder(Order.asc("name"));

        List<ProcessType> list = getHibernateTemplate().findByCriteria(crit, 0, autoCompleteMax);

        return list;

    }

    public Loadable save(Loadable loadable) {
        getHibernateTemplate().saveOrUpdate(loadable);
        return loadable;
    }

    public void delete(Loadable loadable) {
        getHibernateTemplate().delete(loadable);
        getHibernateTemplate().flush();
    }

    /**
     * Change the number of autocomplete matches that are returned.
     * 
     * @param autoCompleteMax
     */
    public void setAutoCompleteMax(int autoCompleteMax) {
        this.autoCompleteMax = autoCompleteMax;
    }

    public int getAutoCompleteMax() {
        return autoCompleteMax;
    }

    /**
     * get the total number of rows without actually returning all rows
     * NOTE: important to set the start row here, otherwise when we start
     * paging, this criteria will be affected and we won't get the first
     * row.
     * 
     * @param criteria
     * @return
     */
    private int getRowCount(DetachedCriteria criteria) {
        criteria.setProjection(Projections.rowCount());
        return ((Integer) getHibernateTemplate().findByCriteria(criteria, 0, 1).get(0)).intValue();
    }

    /**
     * 
     * Posts that are threads will have their threadPost field == null.
     * 
     * Could try to optimize by getting close to: SELECT f.id,
     * f.thread_id, count(s.id) FROM `forumposts` f left JOIN forumposts s
     * on f.id = s.thread_id WHERE f.thread_id IS NULL group by f.id
     * 
     * @param topicName
     * 
     */
    public PostsList getThreads(Class<? extends ForumPost> forumClass, String topicName, long topicID, int start,
            int max) {

        System.out.println("start " + start + " max " + max);

        DetachedCriteria crit = DetachedCriteria.forClass(forumClass, "fp")
                .add(Expression.and(Expression.eq(topicName, topicID), Expression.isNull("threadPost")))
                .addOrder(Order.desc("date"));

        // alternative
        // String query = "select post, count(rp) from " + forumClass
        // + " post left join post.replies as rp where post."
        // + topicName
        // + " = ? and post.threadPost is null group by post."
        // + topicName + " order by post.date desc ";
        // List<Object[]> res = finder(query, topicID);
        // List<ForumPost> posts = new ArrayList<ForumPost>(res.size());
        // for (Object[] objects : res) {
        // ForumPost fp = (ForumPost) objects[0];
        // long count = (Long) objects[1];
        // fp.setReplyCount((int) count);
        // posts.add(fp);
        // }

        List<ForumPost> posts = getHibernateTemplate().findByCriteria(crit, start, max);

        // set the reply count so we can have this information w/o
        // loading
        // the actual set.
        for (ForumPost fp : posts) {
            fp.setReplyCount(fp.getReplies().size());
        }

        PostsList rtn = new PostsList(posts, getRowCount(crit));

        return rtn;
    }

    private List finder(String hql, Object... args) {
        return getHibernateTemplate().find(hql, args);
    }

    public PostsList getPostsForThread(ForumPost post, int start, int max) {
        DetachedCriteria crit = DetachedCriteria.forClass(ForumPost.class)
                .add(Expression.or(Expression.eq("threadPost.id", post.getId()), Expression.eq("id", post.getId())))
                .addOrder(Order.asc("date"));

        List<ForumPost> posts = getHibernateTemplate().findByCriteria(crit, start, max);

        PostsList rtn = new PostsList(posts, getRowCount(crit));

        return rtn;
    }

    public PostsList getSchoolThreads(long schoolID, int start, int max) {
        return getThreads(SchoolForumPost.class, "school.id", schoolID, start, max);
    }

    public PostsList getUserThreads(long userID, int start, int max) {
        return getThreads(UserForumPost.class, "user.id", userID, start, max);
    }

    public PostsList getRecentForumPosts(int start, int max) {
        DetachedCriteria crit = DetachedCriteria.forClass(ForumPost.class, "fp")
                .add(Expression.isNull("threadPost")).addOrder(Order.desc("date"));

        List<ForumPost> posts = getHibernateTemplate().findByCriteria(crit, start, max);

        PostsList rtn = new PostsList(posts, getRowCount(crit));

        return rtn;
    }

    /**
     * Batch Update in HQL
     * http://www.hibernate.org/hib_docs/reference/en/html/batch.html#batch-direct
     */
    public void incrementSchoolPopularity(final School school) {
        getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {

                String hql = "update School set popularityCounter = popularityCounter + 1 where id = :id";
                int updated = session.createQuery(hql).setLong("id", school.getId()).executeUpdate();

                return updated;
            }
        });

    }

    public List<User> getUsersInterestedIn(School school) {
        return getUsersInterestedIn(school, 10);
    }

    public List<User> getUsersInterestedIn(School school, int max) {
        DetachedCriteria crit = DetachedCriteria.forClass(Application.class, "app")
                .add(Expression.eq("school", school));

        List<Application> applications = getHibernateTemplate().findByCriteria(crit, 0, max);

        List<User> users = new ArrayList<User>(applications.size());
        for (Application app : applications) {
            users.add(app.getUser());
        }
        return users;
    }
}