2012-10-17 77 views
1

我使用hibernate 3和spring。 当我启动一个线程发生了异常:线程和休眠会话的问题

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 

我不知道如何脱离实体或关闭会话使用这种架构。 我欣赏一些帮助。

CommunicationService.sendCommunications()代码:

public void sendCommunications(HibernateMessageToSendRepository messageToSendRepository) { 
    Long messageId = new Long(41); //this is only for test. the idea is get a list of id and generate a thread group. 
    MessageSender sender = SmsSender(messageId, messageToSendRepository); 
    sender.start(); 
} 

调用sendCommunications代码:

ApplicationContext appCont = new ClassPathXmlApplicationContext("appContext.xml");  
ServiceLocator serviceLocator = ServiceLocator.getInstance(); 
HibernateMessageToSendRepository messageToSendRepository = (HibernateMessageToSendRepository) appCont.getBean("messageToSendRepository"); 

CommunicationService communication = serviceLocator.getCommunicationService(); 
communication.sendCommunications(messageToSendRepository); 

SmsSender(延伸自messageSender,和(线程))代码:

public class SmsSender extends MessageSender { 

    public SmsSender(Long messageToSendId, HibernateMessageToSendRepository messageToSendRepository) { 
     super(messageToSendRepository); 
     MessageToSend messageToSendNew = this.messageToSendRepository.getById(messageToSendId);  
     this.messageToSend = messageToSendNew; 
    } 

    public void run() { 
     try { 
      MessageToSendSms messageToSendSms = (MessageToSendSms) this.messageToSend; 
      Iterator<CustomerByMessage> itCbmsgs = messageToSendSms.getCustomerByMessage().iterator();   
      while (itCbmsgs.hasNext()) {     
       CustomerByMessage cbm = (CustomerByMessage) itCbmsgs.next();       

       //sms sending 
       this.getGateway().sendSMS(cbm.getBody(), cbm.getCellphone());      
       cbm.setStatus(CustomerByMessageStatus.SENT_OK); 
       cbm.setSendingDate(Calendar.getInstance().getTime());    
      }   

      messageToSendSms.getMessage().setStatus(messageToSendStatus.ALL_MESSAGES_SENT); 
      this.messageToSendRepository.update(messageToSendSms);  
     } catch (Exception e) {   
      this.log.error("Error en sms sender " + e.getMessage()); 
     } 

    } 
} 

MessageToSendRepository代码:

public void update(MessageToSend messageToSend) { 
    try { 
     this.getSession().update(messageToSend); 
    } catch (HibernateException e) { 
     this.log.error(e.getMessage(), e); 
     throw e; 
    } 
} 

回答

0

您需要在检索它之后,但在与另一个线程共享之前,分离messageToSendNew。您可以通过在休眠会话中调用Session.close()来分离该对象。

警告您必须急切地填充所有您需要的字段。

如果您需要重新连接新会话,则可以使用merge()方法。

+0

什么代码我必须写入messageToSend.detach(){....}? – user1750751

+0

我的糟糕'detach()'是API的一部分,分离对象的适当方式是关闭会话。 – nsfyn55