我正在开发一个软件的一部分,它有两个模块(邮件和网络服务)。但我的代码中有一些混乱,我认为我的方式错误/做得不好/困难。有人可以帮我克服这些吗?问题是hibernate正在关闭会话。
这是我的pom结构
-- root
-- mail
-- web-service
需要注意的是,我的spring bootstrapping,appContext.xml,持久化上下文都是托管我的web服务模块,我在我的web服务模块中使用邮件模块作为依赖jar。
我的appContext.xml是这样的,
<context:component-scan base-package="com.it.ese.orbitws,com.it.ese.orbitmail" />
<context:annotation-config />
<tx:annotation-driven />
<!-- enables interpretation of the @PersistenceUnit/@PersistenceContext annotations providing convenient
access to EntityManagerFactory/EntityManager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url" value="jdbc:sqlserver://localhost:1433;database=ORBIT_RC" />
<property name="username" value="sa" />
<property name="password" value="sa" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.SQLServerDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
<qualifier value="tx"/>
</bean>
我想让邮件模块尽可能独立。邮件配置也来自数据库表:
table : "custom":(smtp,global_sender)
所以我创建了自己的JavaMailSenderImpl
,我在这里覆盖了这样的getHost方法。我把它作为spring @Component
。我的困惑在于代码中的注释。
package com.it.ese.mail
@Component
public class OrbitJavaMailSenderImpl extends JavaMailSenderImpl{
private EntityManager entityManager;
private String smtp=null;
private OrbitJavaMailSenderImpl() {
}
// I have used PersistenceContextType.EXTENDED because without this,it says
// Hibernate Session is closed.But using EXTENDED is a bad thing?or it's ok?
@PersistenceContext (type= PersistenceContextType.EXTENDED)
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
//There is no Bean for CUStom TABLE so far in persistence.xml.Should I do that too?
@Transactional(readOnly=true)
public String getSMTPAddress() {
String host="mail.esolutionss-europe.com";
try{
host= this.entityManager.createNativeQuery("SELECT smtp FROM CUSTOM")
.getSingleResult().toString();
}catch(Exception e){
System.out.println("error getting host:"+e.toString());
}
return host;
}
}
在网络服务模块中,我有一个服务NotificationService
,我正在注入春季邮件服务。
package com.it.ese.ws.service
public class NotificationService implements INotificationService {
private EntityManager entityManager;
private String sender=null;
final static Logger logger = Logger.getLogger(NotificationService.class);
@PersistenceContext (type= PersistenceContextType.EXTENDED)
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
//Also here if I don't use EXTENTED persistence context,it gives me error as hibernate session is closed.
@Transactional(readOnly=true)
public String getGlobalSender() {
String sender="a1@xxx.com";
try{
sender= entityManager.createNativeQuery("SELECT Global_email FROM CUSTOM")
.getSingleResult().toString();
}catch(Exception e){
}
return sender;
} /*other methods*/ }
为什么我的EntityManager会关闭?这个Container管理好了吗?是什么导致了封闭的选择?
答案 0 :(得分:2)
不要使用PersistenceContextType.EXTENDED
(除非你非常清楚自己在做什么)。 See here有详细解释。
答案 1 :(得分:2)
我找到了解决方案。我犯了一个错误。我做的是我有一个像
这样的方法public String getX(){
return getY()
}
从getX我调用getY,其中有@Transactional我实际使用的是Entity Manager。 问题是我没有使用@Transactional所以它说会话已关闭。 现在我确实喜欢,
@Transactional
public String getX(){ //getX() is just a wrapper for some reason :)
return getY();
}
现在一切顺利。但这是正当理由还是其他什么?