java - Spring + Hibernate 控制台应用程序

标签 java spring hibernate spring-mvc console-application

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

  1. 对象

在主项目中,我只是将这些项目添加到 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);
    }

Spring 服务.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>

spring-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>

@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,并且配置不允许在此处创建非事务性 session 在 org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356) 异常.. 有趣的是 - 如果我将 @Transactional 添加到 systemGetList() - 工作正常。但我不想为所有选择语句添加事务...... 并且相同的代码(没有交易)在网站本身上运行良好..

有什么帮助吗?提前谢谢你。

最佳答案

您已将您的服务方法指定为事务性

<tx:annotation-driven />

在选择/只读方法上添加@Transactional(readOnly = true)

关于java - Spring + Hibernate 控制台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23262986/

相关文章:

java - 从不同的对象访问对象的内部类

java - 编译错误java.lang.nullpointerException

java - Quartz Scheduler - OC4J 的多个进程 ID 运行同一实例,每个进程 ID 都得到调度

java - Hibernate Reimb 未映射

java - 如何禁用 Spring/Hibernate/Hazelcast 联合缓存?

java - GWT 的 JQueryUI

java - 为什么在 REPL 中没有观察到通配符类型和存在类型之间指定的等价性

java - Couchbase N1ql 在 Java 中急切地查询获取

java - 如何防止@ModelAttribute 在方法中实例化日历

java - 如何避免: "The expression of type List needs unchecked conversion to conform to.."