【发布时间】:2014-06-09 09:20:36
【问题描述】:
一些史前史.. 我有一个使用 Spring 和 Hibernate 编写的基于 Web 的企业 CRM 系统。有很多任务应该系统地完成,例如提醒或电子邮件通知。现在它被实现为一个单独的控制器,从 cron 调用。除了某些任务非常“繁重”并且占用大量 Tomcat 资源这一事实之外,一切都运行良好。所以我决定将它们拆分成不同的 Java 控制台应用程序。为了使用相同的对象和服务,我将主项目拆分为单独的项目(库):
- 对象
- 道
在主项目中,我只是将这些项目添加到 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-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>
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, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356) 异常而失败。有趣的是 - 如果我将@Transactional 添加到systemGetList() - 工作正常。但我不想为所有选择语句添加事务......
并且相同的代码(没有事务)在网站本身上也能正常工作..
有什么帮助吗?提前谢谢你。
【问题讨论】:
标签: java spring hibernate spring-mvc console-application