【问题标题】:Problems with threads and hibernate sessions线程和休眠会话的问题
【发布时间】:2012-10-17 14:43:25
【问题描述】:

我正在使用休眠 3 和弹簧。 当我启动一个线程时发生了异常:

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

【问题讨论】:

    标签: java multithreading spring hibernate repository


    【解决方案1】:

    您需要在检索到 messageToSendNew 之后将其分离,但在与其他线程共享之前。您可以通过在休眠会话上调用 Session.close() 来分离对象。

    请注意,您必须急切地填充您需要的所有字段。

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

    【讨论】:

    • 我的错误 detach() 是 API 的一部分,分离对象的适当方法是关闭会话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2013-12-07
    • 2017-11-19
    • 2011-10-25
    相关资源
    最近更新 更多