Я хочу вставить 11000 записей по 1000 штук, используя JDBI, чтобы все сохранялось или не сохранялось вообще. В настоящее время выдает ошибку следующим образом - PullRequest
0 голосов
/ 31 мая 2018

Мой код похож на

Class Employee
{
    @ColumnName("empid")
    public int empid;

    @ColumnName("empname")
    public String empname;

    @ColumnName("experience")
    public int experience;

}

, затем

List<Employee> lstEmployee = new ArrayList<>();
for (int i = 1; i < 10000; i++) {
    lstEmployee.add(new Employee(i, "abcazsa", i));
}
UserDAOImpl obj = new UserDAOImpl(new JdbiHelper().getDBI());
obj.insertrecords(lstEmployee);

и

@BatchChunkSize(1000)
int insertRecords(@BindBeanList(propertyNames = {"empid", "empname", "experience"}, value = "values") List<Employee> lstEmp);

и последний

public int insertrecords(List<Employee> lstEmp)
    {
        int cnt = 0;
        try (Handle open = jdbi.open()) {
            UserDAO attach = open.attach(UserDAO.class);
        }
        catch(Exception e)
        {
            throw e;

        }

        System.out.println("After catch");
        return cnt;
    }
}
 Exception in thread "main" org.jdbi.v3.core.statement.UnableToExecuteStatementException: org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend. [statement:"INSERT INTO public."Employee" (empid, empname, experience) VALUES <values>", rewritten:"INSERT INTO public."Employee" (empid, empname, experience) VALUES (:__values_0_empid,:__values_0_empname,:
 finder:[]}]
    at org.jdbi.v3.core.statement.SqlStatement.internalExecute(SqlStatement.java:1464)
    at org.jdbi.v3.core.result.ResultProducers.lambda$returningUpdateCount$0(ResultProducers.java:39)
    at org.jdbi.v3.core.statement.Update.execute(Update.java:53)
    at org.jdbi.v3.core.statement.Update.execute(Update.java:41)
    at org.jdbi.v3.sqlobject.statement.internal.SqlUpdateHandler.lambda$new$1(SqlUpdateHandler.java:59)
    at org.jdbi.v3.sqlobject.statement.internal.SqlUpdateHandler.lambda$configureReturner$3(SqlUpdateHandler.java:74)
    at org.jdbi.v3.sqlobject.statement.internal.CustomizingStatementHandler.invoke(CustomizingStatementHandler.java:157)
    at org.jdbi.v3.sqlobject.statement.internal.SqlUpdateHandler.invoke(SqlUpdateHandler.java:30)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$null$13(SqlObjectFactory.java:162)
    at org.jdbi.v3.core.ConstantHandleSupplier.invokeInContext(ConstantHandleSupplier.java:52)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$createInvocationHandler$14(SqlObjectFactory.java:161)
    at com.sun.proxy.$Proxy11.insertRecords(Unknown Source)
    at com.samples.UserDAOImpl.insertrecords(UserDAOImpl.java:48)
    at com.samples.BulkInsert.main(BulkInsert.java:28)
    Suppressed: org.jdbi.v3.core.transaction.TransactionException: Failed to test for transaction status
        at org.jdbi.v3.core.transaction.LocalTransactionHandler.isInTransaction(LocalTransactionHandler.java:134)
        at org.jdbi.v3.core.Handle.isInTransaction(Handle.java:259)
        at org.jdbi.v3.core.Handle.close(Handle.java:123)
        at com.samples.UserDAOImpl.insertrecords(UserDAOImpl.java:57)
        ... 1 more
    Caused by: org.postgresql.util.PSQLException: This connection has been closed.
        at org.postgresql.jdbc.PgConnection.checkClosed(PgConnection.java:767)
        at org.postgresql.jdbc.PgConnection.getAutoCommit(PgConnection.java:728)
        at org.jdbi.v3.core.transaction.LocalTransactionHandler.isInTransaction(LocalTransactionHandler.java:131)
        ... 4 more
Caused by: org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:333)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155)
    at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:144)
    at org.jdbi.v3.core.statement.SqlStatement.internalExecute(SqlStatement.java:1451)
    ... 13 more
Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 32997
    at org.postgresql.core.PGStream.sendInteger2(PGStream.java:224)
    at org.postgresql.core.v3.QueryExecutorImpl.sendParse(QueryExecutorImpl.java:1440)
    at org.postgresql.core.v3.QueryExecutorImpl.sendOneQuery(QueryExecutorImpl.java:1762)
    at org.postgresql.core.v3.QueryExecutorImpl.sendQuery(QueryExecutorImpl.java:1326)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:298)
    ... 18 more

1 Ответ

0 голосов
/ 13 июня 2018

Это решается с помощью процесса транзакции.

код как ниже

public int insertrecords(List<Employee> lstEmp) {

           int cnt = 0;

           Handle open = null;

           try {

                open = jdbi.open();

                open.begin();

                UserDAO attach = open.attach(UserDAO.class);

                System.out.println("Start");


                while (true) {

                     List<Employee> lstTemp = lstEmp.stream().limit(3000).collect(Collectors.toList());

                     int tempcnt = attach.insertRecords(lstTemp);

                     lstEmp.removeAll(lstTemp);

                     cnt = cnt + tempcnt;

                     if (lstEmp.isEmpty()) {

                           break;

                     }

                }

                if (open != null && open.isInTransaction()) {

                     System.out.println("Commit");

                     open.commit();

                }





                System.out.println(cnt);

                System.out.println("End");

           } catch (Exception e) {

                if (open != null) {

                     open.rollback();

                }

                throw e;



          }

           return cnt;

     }
...