简体   繁体   English

如何向Postgresql CopyManager指示会话实例

[英]How to indicate a session instance to Postgresql CopyManager

I have a java web project using hibernate to manage database operations. 我有一个使用休眠模式来管理数据库操作的Java Web项目。

There are two SQLs executed in order: 有两个按顺序执行的SQL:

  1. execute "CREATE TEMP temp_table...;" 执行“ CREATE TEMP temp_table ...;” through hibernate native sql query. 通过休眠本机sql查询。
  2. execute "COPY temp_table from SDTIN" through org.postgresql.copy.CopyManager to transmit a csv file into temp_table. 通过org.postgresql.copy.CopyManager执行“从SDTIN复制TEMP_table”,以将CSV文件传输到temp_table。

My code: 我的代码:

public boolean loadElectricFishData(Integer fileId, File eventfile, File samplefile) {
    Session session = stagingSessionFactory.getCurrentSession();
    String elecCountTableName = "temp_eb_elec_count_" + fileId;

    return createTable(session, elecCountTableName , "nemostaging.eb_elec_count")
            && copyTableFromCSV(session, elecCountTableName, eventfile) ? true : false;
}

private boolean createTable(Session session, String tableName, String likeTableName) {
    SQLQuery query = session.createSQLQuery("CREATE TABLE nemostaging." + tableName + " (LIKE " + likeTableName + " INCLUDING ALL)");
    query.executeUpdate();
    session.flush();
    session.close();
    return true;
}

private boolean copyTableFromCSV(Session session, final String tableName, final File csv) {
    SessionImpl sessionImpl = (SessionImpl)session;
    Connection connection = sessionImpl.getTransactionCoordinator().getJdbcCoordinator().getLogicalConnection().getConnection();
    FileReader fileReader = null;
    try {
        CopyManager copyManager = new CopyManager((BaseConnection) connection);
        fileReader = new FileReader(csv);
        copyManager.copyIn("COPY nemostaging." + tableName + " FROM STDIN DELIMITER ',' CSV HEADER", fileReader);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (fileReader != null) {
            try {
                fileReader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    return false;
}

My problem is I need the same session for these two operations, because temporary table is invisible to another session. 我的问题是这两个操作需要相同的会话,因为临时表对另一个会话不可见。 While CopyManager will not reuse the same session. 而CopyManager不会重用同一会话。 Anyone has an idea how I can indicate the current session to org.postgresql.copy.CopyManager but not only the current connection? 任何人都有一个主意,该如何指示org.postgresql.copy.CopyManager的当前会话,而不只是当前的连接?

Thanks a lot! 非常感谢!

------Update-2015-11-13----- Hi Craig Ringer, I tried your suggestion, but got an exception: ------ Update-2015-11-13 -----嗨,克雷格·林格,我尝试了您的建议,但有一个例外:

java.lang.reflect.UndeclaredThrowableException at com.sun.proxy.$Proxy20.unwrap(Unknown Source) at nz.co.niwa.nemo.uploadservice.core.dao.impl.StagingLoadDataDaoImpl$1.execute(StagingLoadDataDaoImpl.java:88) at org.hibernate.jdbc.WorkExecutor.executeWork(WorkExecutor.java:54) at org.hibernate.internal.SessionImpl$2.accept(SessionImpl.java:1933) at org.hibernate.internal.SessionImpl$2.accept(SessionImpl.java:1930) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.coordinateWork(JdbcCoordinatorImpl.java:211) at org.hibernate.internal.SessionImpl.doWork(SessionImpl.java:1951) at org.hibernate.internal.SessionImpl.doWork(SessionImpl.java:1937) at nz.co.niwa.nemo.uploadservice.core.dao.impl.StagingLoadDataDaoImpl.loadSpotlightData(StagingLoadDataDaoImpl.java:85) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl. com.sun.proxy。$ Proxy20.unwrap中的java.lang.reflect.UndeclaredThrowableException(nz.co.niwa.nemo.uploadservice.core.dao.impl.StagingLoadDataDaoImpl $ 1.execute(StagingLoadDataDaoImpl.java:88)在org.hibernate.jdbc.WorkExecutor.executeWork(WorkExecutor.java:54)在org.hibernate.internal.SessionImpl $ 2.accept(SessionImpl.java:1933)在org.hibernate.internal.SessionImpl $ 2.accept(SessionImpl.java) :1930),位于org.hibernate.internal.SessionImpl.doWork(SessionImpl.java:1951)的org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.coordinateWork(JdbcCoordinatorImpl.java:211),位于org.hibernate.internal.SessionImpl。 doWork(SessionImpl.java:1937)位于nz.co.niwa.nemo.uploadservice.core.dao.impl.StagingLoadDataDaoImpl.loadSpotlightData(StagingLoadDataDaoImpl.java:85)位于sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)。在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.invoke.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90) at org.springframework.aop.framework.ReflectiveMethodInvocation.procee 的org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)的java.lang.reflect.Method.invoke(Method.java:597)的java.25) org.org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)上的org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)上的.invokeJoinpoint(ReflectiveMethodInvocation.java:183)。 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)上的springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation。 java:172)在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)在org.springframework.aop.framework.ReflectiveMethodInvocation.procee d(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy.$Proxy14.loadSpotlightData(Unknown Source) at nz.co.niwa.nemo.uploadservice.core.manage.impl.StagingLoadDataManageImpl.loadSpotlightData(StagingLoadDataManageImpl.java:30) at nz.co.niwa.nemo.uploadservice.core.service.impl.StagingLoadDataServiceImpl.loadSpotlightData(StagingLoadDataServiceImpl.java:44) at nz.co.niwa.nemo.uploadservice.core.test.service.StagingLoadDataServiceTest.testLoadSpotlightData(StagingLoadDataServiceTest.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.Ref d(ReflectiveMethodInvocation.java:172)在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)在com.sun.proxy。$ Proxy14.loadSpotlightData(未知源)在nz.co.niwa.nemo nz.co.niwa.nemo.uploadservice.core.service.impl.StagingLoadDataServiceImpl.loadSpotlightData(StagingLoadDataServiceImpl.java:44)上的.uploadservice.core.manage.impl.StagingLoadDataManageImpl.loadSpotlightData(StagingLoadDataManageImpl.java:30)在nz.co. .niwa.nemo.uploadservice.core.test.service.StagingLoadDataServiceTest.testLoadSpotlightData(StagingLoadDataServiceTest.java:39)位于sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法),位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java :)在java.lang.reflect.Method.invoke(Method.java:597)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 45)在org.junit.internal.runners.model.Ref lectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunn org.junit.runners.model.FrameworkMethod.invoke上的lectiveCallable.run(ReflectiveCallable.java:15)org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)上的Explosively(FrameworkMethod.java:42)在org.springframework.org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)在org.springframework.org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)在org.springframework org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)上的.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)在org.junit.runners.BlockJUnit4ClassRunner.runChild上(BlockJUnit4ClassRunner.java:47)在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:231)在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:60)在org.junit.runners。 org.junit.runners.ParentRunn上的ParentRunner.runChildren(ParentRunner.java:229) er.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.int 在org.junit.runners.er.access $ 000(ParentRunner.java:50)在org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:$2.evaluate(ParentRunner.java:222) 61)在org.springit.runners.ParentRunner.run(ParentRunner.java:300)在org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)在org.springframework.test.context org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)的.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)在org.eclipse.jdt.internal.junit.runner.TestExecutionion org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)上的.run(TestExecution.java:38)在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner。 .java:675),位于org.eclipse.jdt.int的org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) ernal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:130) at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) ... 55 more Caused by: java.sql.SQLException: Cannot unwrap to org.postgresql.copy.CopyManager at org.postgresql.jdbc4.AbstractJdbc4Connection.unwrap(AbstractJdbc4Connection.java:269) ... 61 more ernal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)由以下原因引起:java.lang.reflect.InvocationTargetException在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java :39),位于org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler的java.lang.reflect.Method.invoke(Method.java:597)的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)处。 org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)处的continueInvocation(ConnectionProxyHandler.java:130)... 55更多原因:java.sql.SQLException:无法解包到org。 org.postgresql.jdbc4.AbstractJdbc4Connection.unwrap(AbstractJdbc4Connection.java:269)的postgresql.copy.CopyManager ... 61更多

My code: 我的代码:

public boolean loadSpotlightData(final Integer fileId, final File datafile) {
    final String spotCountTableName = "tmp_eb_spot_count_" + fileId;
    Session session = stagingSessionFactory.getCurrentSession();
    SQLQuery query = session.createSQLQuery("CREATE TEMP TABLE " + spotCountTableName + " (LIKE nemostaging.eb_spot_count INCLUDING ALL)");
    query.executeUpdate();
    session.doWork(new Work() {
        @Override
        public void execute(Connection connection) throws SQLException {
            CopyManager copyManager = connection.unwrap(org.postgresql.copy.CopyManager.class);
            FileReader fileReader = null;
            try {
                fileReader = new FileReader(datafile);
                copyManager.copyIn("COPY " + spotCountTableName + " FROM STDIN DELIMITER ',' CSV HEADER", fileReader);
            } catch (SQLException e) {
                LOG.error("Errors occur while COPY nemostaging." + spotCountTableName + " FROM STDIN DELIMITER ',' CSV HEADER;", e);
            } catch (FileNotFoundException e) {
                LOG.error("The CSV file cannot be found while copying into database.", e);
            } catch (IOException e) {
                LOG.error("Errors occur while reading the csv file.", e);
            } finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        LOG.error("Errors occur while closing file reader.", e);
                    }
                }
            }
        }
    });

    Query query1 = session.getNamedQuery("staging.loadSpotlightData");
    query1.setParameter("fileId", fileId);
    query1.list();

    return true;
}

What you must do is run the Hibernate query, then ask the Hibernate Session to get the underlying Connection object that implements org.postgresql.PGConnection and use that. 您必须做的是运行Hibernate查询,然后要求Hibernate Session获取实现org.postgresql.PGConnection的基础Connection对象并使用它。

You used to be able to unwrap the session with the Session.connection() method, but that's deprecated now. 您曾经能够使用Session.connection()方法解开会话,但是现在不建议使用。 Instead use the doWork API . 而是使用doWork API The java.sql.Connection you get passed is probably wrapped by your connection pool, too, so you might have to unwrap that to get the actual connection object. 您传递的java.sql.Connection也可能由连接池包装,因此您可能必须将其拆包以获取实际的连接对象。 If you're using JDBC4 drivers and pools (you should be), just use the unwrap(...) method from the Wrapper interface implemented by Connection , eg unwrap(org.postgresql.copy.CopyManager.class) . 如果正在使用JDBC4驱动程序和池(应该使用),则只需使用Connection实现的Wrapper接口中unwrap(...)方法即可 ,例如unwrap(org.postgresql.copy.CopyManager.class)

Something like (untested): 像(未经测试的):

session.doWork(
    new Work() {
        public void execute(Connection connection) throws SQLException 
        { 
            CopyManager cm = connection.unwrap(org.postgresql.copy.CopyManager.class);
            ... do stuff ...
        }
    }
);

You can't create a new, separate connection directly from the DriverManager and use it with another session's temp tables. 您不能直接从DriverManager创建新的单独连接,也不能将其与另一个会话的临时表一起使用。 Nor do you need to. 您也不需要。 It's better to unwrap the pooled connection from the Hibernate session. 最好从Hibernate会话中取消池化连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM