Hibernate-сессия закрывается с помощью Entity Manager - PullRequest
2 голосов
/ 25 июля 2011

Я занимаюсь разработкой части программного обеспечения, которое состоит из двух модулей (почта и веб-сервис). Но у меня есть некоторая путаница в моем коде, который я считаю, что я делаю неправильно / плохо / трудными способами. Может ли кто-нибудь помочь мне преодолеть это? Проблема в спящем режиме - закрытие сессии.

Вот моя структура пома

 -- root
    -- mail
    -- web-service

Следует отметить, что моя пружинная начальная загрузка, appContext.xml, контекст постоянства все управляются моим модулем веб-службы, и я использую почтовый модуль в качестве jar зависимости в моем модуле веб-службы.

My, 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 закрывается? Управляется ли этот контейнер? что вызвало закрытый разрыв?

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Я нашел свое решение. Я допустил ошибку. что я сделал, у меня был метод, как

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(); 
} 

Теперь все гладко. Но была ли это действительная причина или что-то еще?

2 голосов
/ 25 июля 2011

Не используйте PersistenceContextType.EXTENDED (если вы не очень хорошо знаете, что делаете). См. Здесь для подробного объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...