Spring + Hibernate控制台应用程序

时间:2014-04-24 07:51:43

标签: java spring hibernate spring-mvc console-application

一些史前史... 我有一个用Spring和Hibernate编写的基于Web的企业CRM系统。应该系统地完成许多任务,例如提醒或电子邮件通知。现在,它是作为一个单独的控制器实现的,它是从cron调用的。一切都很好,除了一些任务是非常重的"并占用了很多Tomcat的资源。所以我决定将它们分成不同的java控制台应用程序。为了使用相同的对象和服务,我将主项目拆分为单独的项目(库):

  1. 物件
  2. DAO
  3. 在主项目中,我刚刚将这些项目添加到BuildPath中,因此我可以毫无问题地使用所有对象和服务。

    现在我开始实现第一个控制台实用程序并面临一些问题。看看。

    public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-service.xml", "spring-hibernate.xml");
    
            try {
                MessageSourceEx messageSource = new MessageSourceEx((ResourceBundleMessageSource) ctx.getBean("messageSource"));
                ITasksService tasksService = (ITasksService) ctx.getBean("tasksService");
                NotificationsService notificationsService = (NotificationsService) ctx.getBean("notificationsService");
    
                List<Task> tasks = tasksService.systemGetList();
                for (Task t: tasks) {
                    Locale userLocale = t.getCreator().getCommunicationLanguageLocale();
                    EmailNotification reminder = new EmailNotification(t.getCreator().getEmail(), 
                            messageSource.getMessage(userLocale, "notifications.internal.emails.task.subject"), 
                            messageSource.getMessage(userLocale, "notifications.internal.emails.task.text", 
                                    t.getCreator().getNickname(),
                                    t.getName(),
                                    t.getDescription(),
                                    AppConfig.getInstance().getUrl(),
                                    t.getId()), 
                            userLocale, t.getCreator());
                    notificationsService.email.send(reminder);
                    if (reminder.getState() == EmailNotificationSendState.Sent) {
                        t.setReminderSent(true);
                        tasksService.save(t);
                    }
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                ((ConfigurableApplicationContext)ctx).close();
            }
    
            System.exit(0);
        }
    

    弹簧service.xml中

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
        <context:annotation-config />
        <context:component-scan base-package="com.dao,com.service,com.notifications,com.interfaces" />
        <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="com.Resources" />
        </bean>
    </beans>
    

    弹簧hibernate.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.1.xsd">
        <tx:annotation-driven />
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:/hibernate.properties" />
        </bean>
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${hibernate.connection.driver_class}" />
            <property name="url" value="${hibernate.connection.url}" />
            <property name="username" value="${hibernate.connection.username}" />
            <property name="password" value="${hibernate.connection.password}" />
        </bean>
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="annotatedClasses">
                <list>
                    <value>com.data.Task</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                    <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                    <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
                    <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
               </props>
            </property>
        </bean>
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    </beans>
    

    DAO

    @Component
    public class TasksDAO {
    
        /**
         * Retrieves a list of tasks
         * 
         * @return List of tasks
         */
        @SuppressWarnings({ "unchecked" })
        public List<Task> systemGetList() {
            Session session = SessionFactoryUtils.getSession(sessionFactory, false);
            List<Task> result = null;
            Date now = new Date();
    
            Criteria query = session.createCriteria(Task.class)
                    .add(Restrictions.le("remindTime", DateUtilsEx.addMinutes(now, 3)))
                    .add(Restrictions.eq("reminderSent", false))
                    .addOrder(Order.asc("remindTime"));
    
            result = query.list();
            if (result == null)
                result = new ArrayList<Task>();
    
            return result;
        }
    }
    

    服务

    @Service
    public class TasksService implements ITasksService {
    
        /**
         * 
         */
        @Override
        public List<Task> systemGetList() {
            return tasksDAO.systemGetList();
        }
    }
    

    它因No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here at org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356)例外而失败。有趣的是 - 如果我将@Transactional添加到systemGetList() - 工作正常。但我不想为所有选择语句添加交易...... 并且相同的代码(没有事务)在网站本身上运行良好..

    有任何帮助吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

您已将服务方法指定为“交易”

<tx:annotation-driven />

在select / read only方法

上添加@Transactional(readOnly = true)