oracle 会话/实体管理器已关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46754143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:28:18  来源:igfitidea点击:

session/entitymanager is closed

springoraclehibernate

提问by sagar limbu

i have this hibernate dao and it works fine while testing in my local machine. but for some transaction it throws IllegalStateException. i believe it is because multiple users hitting at same time.(i may be wrong).

我有这个 hibernate dao,在我的本地机器上测试时它工作正常。但是对于某些事务,它会抛出 IllegalStateException。我相信这是因为多个用户同时点击。(我可能错了)。

UpdatePaymentDao

更新PaymentDao

@Repository
public class UpdatePaymentImpl implements UpdatePayment {


    @Autowired
    SessionFactory sessionFactory;
    Session session;
    Transaction trans;

    private static final long LIMIT = 100000000000L;
    private static final long LIMIT2 = 10000000000L;
    private static long last = 0;


    public static long getUniqueID() {
        // 10 digits.
        long id = (System.currentTimeMillis() % LIMIT) + LIMIT2;
        System.out.println("id"+id);
        System.out.println("system time"+System.currentTimeMillis());
        System.out.println("milssiiiiii=============="
                + System.currentTimeMillis());
        if (id <= last) {
            id = (last + 1) % LIMIT;
        }
        return last = id;
    }

    public PaymentResponse updatePayment(@RequestBody FcgoUpdateParam updateParam) {
        FcgoUpdateParam fcgoUpdateParam= new FcgoUpdateParam();
        Double amountPaid=Double.parseDouble(updateParam.getAmountPaid());
        String depositSlioNo=updateParam.getVoucherno();
        String masterId= updateParam.getMasterId();
        String advCode=updateParam.getAdvCode();

        PaymentResponse paymentResponse = new PaymentResponse();

        long uuid = getUniqueID();

        try{

            System.out.println("generated uuid "+uuid);


            DateFormat dateFormat =new SimpleDateFormat("dd-MMM-yy h.mm.ss.000000000 a");
            SimpleDateFormat dms = new SimpleDateFormat("dd-MM-yyyy");
            String cdate = updateParam.getChallanDate();
            Date ddate= dms.parse(cdate);
            String challandate = dateFormat.format(ddate);

            String office = updateParam.getOffice();
            String username = updateParam.getUsername();
            Long id = getIdOnChallanTable()+1L;

            String challanid = String.valueOf(uuid);
            ChallanEntity challanEntity = new ChallanEntity();
            challanEntity.setAdvtcode(updateParam.getAdvCode());
            challanEntity.setAmount(amountPaid);
            challanEntity.setName(updateParam.getName());
            challanEntity.setOffice(office);
            challanEntity.setUsername(username);
            challanEntity.setStatus(updateParam.getStatus());
            challanEntity.setChallandate(challandate);
            challanEntity.setChallanid(uuid);
            challanEntity.setChallantime("null");
            challanEntity.setVoucherno(updateParam.getVoucherno());

            System.out.println(challanEntity.getId());

            System.out.println("challan saved");

            session=sessionFactory.openSession();
            trans=session.beginTransaction();

            Query query= session.createQuery("update CandidateappearagainstadvtcodeEntity cd set 

            cd.paymentstatus='Completed',cd.amountpaid=:depoFee,cd.challanid=:challanid where
             cd.studentmasterid=:masterid and cd.advertisementcode=:advCode");
            System.out.println(updateParam.getAdvCode());
            query.setParameter("depoFee",updateParam.getAmountPaid());
            query.setParameter("challanid",challanid);
            query.setParameter("masterid",masterId);
            query.setParameter("advCode",advCode);
            Query query1 =session.createQuery(" update CandidateappeartoadvtnumberEntity cnd

            set cnd.paymentstatus='Completed', cnd.depositedfee=:depofee where
             cnd.studentmasterid=:masterid
            and cnd.advertisementcode=:advcode");
            String masterId1= updateParam.getMasterId();
            String advCode1=updateParam.getAdvCode();
            System.out.println("updateCandidateappearagainstadvtcodeEntity ");

            query1.setParameter("depofee",amountPaid);
            query1.setParameter("masterid",masterId1);
            query1.setParameter("advcode",advCode1);


            //added code
            final long start = System.nanoTime();
            System.out.println("before executing excute update queries");
            System.out.println("checking update query timings");


            query.executeUpdate();
            query1.executeUpdate();
            //added code
            final long end = System.nanoTime();
            System.out.println("after executing two update queries, it took: " +
            ((end - start) / 1000000) + "ms");

            //printing all values for test
            //printing for candidateappearagainstcode table
            System.out.println("printing candidate appear against code table");
            System.out.println("the received challan id is: " +challanid);
            System.out.println("the received deposited fee is :"+amountPaid);
            System.out.println("the received advt code is : "+advCode);
            System.out.println("the received master id is : "+masterId);


            System.out.println("values committed on psc database");
            try {
                final String uri = "http://xx.x.x.xx:xxxx/FcgoApi/api/savePayment";
                RestTemplate restTemplate = new RestTemplate();
                paymentResponse = restTemplate.postForObject(uri, updateParam,
                PaymentResponse.class);
                if (paymentResponse.getVoucherNo() != null) {
                    challanEntity.setVoucherno(paymentResponse.getVoucherNo());
                    session.save(challanEntity);
                    session.update(challanEntity);
                    trans.commit();
                    return paymentResponse;
                }else {
                    trans.rollback();
                }
            }catch (Exception ex){
                ex.printStackTrace();
                trans.rollback();
            }
        }catch (Exception e){
            System.out.println("update error " +e);
            trans.rollback();

        }finally {
            session.close();
        }
        return paymentResponse;
    }

    // [...]
}

applicationContext.xml

应用上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.beans.factory.config.
        PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/WEB-INF/db.properties</value>
        </property>
    </bean>
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.connection.url">
                    jdbc:oracle:thin:@x.x.x.x:1521:xxx</prop>
                <prop key="hibernate.connection.driver_class">
                    oracle.jdbc.driver.OracleDriver</prop>
                <prop key="hibernate.c3p0.timeout">18000</prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.psc</value>
            </list>
        </property>
    </bean>


    <bean id="transactionManager" class="org.springframework.
        orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.
        datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

</beans>

error log:

错误日志:

java.lang.IllegalStateException: Session/EntityManager is closed
        at org.hibernate.internal.AbstractSharedSessionContract.
        checkOpen(AbstractSharedSessionContract.java:328)
        at org.hibernate.engine.spi.SharedSessionContractImplementor
        checkOpen(SharedSessionContractImplementor.java:126)
        at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:669)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:665)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:660)
        at com.psc.dao.UpdatePaymentImpl.updatePayment(UpdatePaymentImpl.java:127)
        at com.psc.services.UpdatePaymentServiceImpl.updatePayment
        (UpdatePaymentServiceImpl.java:26)
        at sun.reflect.GeneratedMethodAccessor92.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
        at java.lang.reflect.Method.invoke(Method.java:508)
        at org.springframework.aop.support.AopUtils
        .invokeJoinpointUsingReflection(AopUtils.java:333)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.
        invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.
        proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor
        .proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.
        invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.
        invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.
        ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy32.updatePayment(Unknown Source)
        at com.psc.controls.UpdatePayment.updatePayment(UpdatePayment.java:26)
        at sun.reflect.GeneratedMethodAccessor91.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
        at java.lang.reflect.Method.invoke(Method.java:508)
        at org.springframework.web.method.support.
        InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.
        InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.
        ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.
        RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.
        RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.
        AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.
        doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet
        .doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet
        .processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet
        .doPost(FrameworkServlet.java:872)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
        at org.springframework.web.servlet.FrameworkServlet
        .service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
        (ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter
        (ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
        (ApplicationFilterChain.java:193)
update error java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@4bbb6b39 is closed

回答by Baptiste Beauvais

You mustn't use the Sessionand Transactionas a class member of your dao like that. Session/EntityManagerare suppose to be scoped by unit of work, they are not thread safe.

你不能像那样使用SessionandTransaction作为你的 dao 的类成员。Session/EntityManager假设受工作单元的限制,它们不是线程安全的。

In your current state, as Spring DI create beans as singleton, if two threads use the dao at the same time the second will overwrite both Sessionand Transactionmembers which is why i suppose you get the IllegalStateExcepion.

在您当前的状态下,由于 Spring DI 将 bean 创建为单例,如果两个线程同时使用 dao,第二个线程将覆盖两者SessionTransaction成员,这就是为什么我想您会得到 IllegalStateExcepion。

You have to make them thread scoped by either using them as variables in methods or, if you don't need hibernate's specific method, you could go for a full JPA configuration in Spring and use @PersistenceContext/@PersistenceUnitto let the framework deal with that issue.

您必须通过将它们用作方法中的变量来使它们成为线程作用域,或者,如果您不需要 hibernate 的特定方法,则可以在 Spring 中进行完整的 JPA 配置,并使用它@PersistenceContext/@PersistenceUnit来让框架处理该问题。

回答by RaM PrabU

The Spring will create a singleton copy of the DA class. In a multi threading scenario when a thread t1 is working on a session/transaction and thread t2 which share same sesion/transacrtion may closeit. So make sure declaring these variable inside your local variable. The Scope of declaration of variable matters here.

Spring 将创建 DA 类的单例副本。在多线程场景中,当线程 t1 正在处理会话/事务,而共享相同会话/事务的线程 t2 可能会 关闭它。因此,请确保在本地变量中声明这些变量。变量声明的范围在这里很重要。