I am developing a part of a software which has two modules(mail and web-service).But I have some confusion in my code which I think that I am doing in wrong way/ in bad way / in difficult ways. Could somebody help me to overcome these? Th problem is hibernate is closing the session.
Here is my pom structure
-- root
-- mail
-- web-service
Point to be noted that my spring bootstrapping,appContext.xml,persistence context are all managed my web-service module and I am using mail module as dependency jar in my web-service module.
My,appContext.xml is like this,
<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 --&g开发者_运维知识库t;
<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>
I wanted to make mail module as independent as possible. Also the mail configuration comes from database table:
table : "custom":(smtp,global_sender)
So I made my own JavaMailSenderImpl
where I override the getHost method like this.I have made this as spring @Component
. My confusions are in comments inside the code.
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;
}
}
In the web service module I have a service NotificationService
where I am injecting spring mail service.
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*/ }
Why my EntityManager is getting closed? Is this Container managed ? what caused the closed sesesion?
Don't use PersistenceContextType.EXTENDED
(unless you know very well what you are doing). See here for a detailed explanation.
I found my solution. I made a mistake. what I did is I had a method like
public String getX(){
return getY()
}
and from getX I call getY which has @Transactional where I actually using Entity Manager. The problem was I did not use @Transactional so it was saying session is closed. Now I did like,
@Transactional
public String getX(){ //getX() is just a wrapper for some reason :)
return getY();
}
Now its all smooth. But was it the valid reason or anything else?
精彩评论