[英]Spring + Hibernate console application
Some prehistory.. I have a web-based corporate CRM system written with Spring and Hibernate. 一些史前史。我有一个用Spring和Hibernate编写的基于Web的企业CRM系统。 There are a lot of tasks that should be done systematically such as reminders or email notifications.. Now it is implemented as a separate Controller wich is called from cron.
应该系统地完成许多任务,例如提醒或电子邮件通知。现在,它是作为一个单独的控制器实现的,它是从cron调用的。 Everything works fine except of the fact that some of tasks are very "heavy" and take a lot of Tomcat's resources.
一切正常,除了一些任务非常“沉重”并占用了很多Tomcat的资源。 So I decided to split them into different java console apps.
所以我决定将它们分成不同的java控制台应用程序。 In order to use the same objects and services I splited the main project into separate projects (libraries):
为了使用相同的对象和服务,我将主项目拆分为单独的项目(库):
In the main project I just added these projects to the BuildPath so I can use all the objects and services without any problem. 在主项目中,我刚刚将这些项目添加到BuildPath中,因此我可以毫无问题地使用所有对象和服务。
Now I started implement the first console utility and facing some issue.. Take a look. 现在我开始实现第一个控制台实用程序并面临一些问题。看一看。
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 弹簧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 弹簧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 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 服务
@Service
public class TasksService implements ITasksService {
/**
*
*/
@Override
public List<Task> systemGetList() {
return tasksDAO.systemGetList();
}
}
It fails with 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)
exception.. What is interesting - if I add @Transactional
to systemGetList()
- works fine. 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)
失败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)
异常中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()
- 工作正常。 But I don't want to add transactions for all select statements... And the same code (without transaction) works fine on web-site itself.. 但是我不想为所有select语句添加事务......并且相同的代码(没有事务)在web站点本身上工作正常。
Any help? 有帮助吗? Thank you in advance.
先感谢您。
You have specified your service methods to be Transactional 您已将服务方法指定为Transactional
<tx:annotation-driven />
Add @Transactional(readOnly = true)
on select/read only methods 在select / read方法上添加
@Transactional(readOnly = true)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.