java - 线程和 hibernate session 的问题

标签 java multithreading spring hibernate repository

我正在使用 hibernate 3 和 spring。 当我启动线程时发生异常:

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

我不知道如何分离实体或关闭此架构的 session 。 我感谢一些帮助。

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

最佳答案

您需要在检索 messageToSendNew 之后、与其他线程共享它之前将其分离。您可以通过在 hibernate session 上调用 Session.close() 来分离该对象。

请注意,您必须尽快填充所需的所有字段。

如果您需要将其与新 session 重新连接,可以使用 merge() 方法。

关于java - 线程和 hibernate session 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12936928/

相关文章:

java - 无法通过 java Runtime.getRuntime.exec() 发送 JSON 字符串;

java - Selenium 3.3.1 : NoDefClassFound (com. google.common.base.Function)

Java 泛型类型参数 Project 不在类型变量 E 的范围内

C# 修改 parallel.foreach 中的 DataRow 数组引用,为什么代码运行正确?

java - 如何在 Java 中访问可运行对象中的变量

java - 基于方法参数的 Autowiring

java - 当 spring 上下文加载失败时停止服务器的已知方法?

java - 创建apk时报错: this class should provide a default constructor,

c++ - std::move 给出了将 std::string 移动到另一个线程的错误

java - 如何在 spring security 中运行自定义登录页面