“偶尔”;“一般错误”;从Java插入POSTGRES数据库时发生

“偶尔”;“一般错误”;从Java插入POSTGRES数据库时发生,java,postgresql,jdbc,jdbc-odbc,Java,Postgresql,Jdbc,Jdbc Odbc,我试图将Java中的一组数据插入Postgres数据库。JVM和数据库都是64位的。查询数据库并查看输出结果表明,在JVM崩溃之前,代码已将54行正确插入数据库。另外五个条目返回相同的错误,我在继续执行之前已将这些错误记录到stderr。这是其中一个错误,它们都具有相同的信息: Could not execute SQL insert: General error Error code: 0 SQL State: S1000 DB Connection Status: OPEN java.sql

我试图将Java中的一组数据插入Postgres数据库。JVM和数据库都是64位的。查询数据库并查看输出结果表明,在JVM崩溃之前,代码已将54行正确插入数据库。另外五个条目返回相同的错误,我在继续执行之前已将这些错误记录到stderr。这是其中一个错误,它们都具有相同的信息:

Could not execute SQL insert: General error
Error code: 0
SQL State: S1000
DB Connection Status: OPEN
java.sql.SQLException: General error
    at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbc.SQLExecute(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(Unknown Source)
    at sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeUpdate(Unknown Source)
    at shadowlandsCrawler.Database.storeAccount(Database.java:70)
    at shadowlandsCrawler.ShadowlandsCrawler.main(ShadowlandsCrawler.java:82)
我进入shell,我能够成功地手动插入错误的数据。对数据的目视检查显示,除了简单的ASCII码外,没有其他内容。我尝试在每次插入后关闭数据库连接,但结果与一个连接上的多个插入相同

虽然JVM崩溃可能与SQL错误有关,但我现在只关心这些异常的原因,而不是崩溃

以下是我的数据库类,访问详细信息不清楚:

import java.sql.*;

public class Database {

    static Database singletonDB;
    private Connection hauntingDB;

    private PreparedStatement statement;

    private Database() throws SQLException, ClassNotFoundException{
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        hauntingDB = DriverManager.getConnection("jdbc:odbc:HauntingAccounts", "REDACTED", "REDACTED");
        String sqlCommand = "INSERT INTO \"Accounts\" (\"Title\", \"Author\", \"Story\", \"Words\") VALUES (?, ?, ?, ?);";
        statement = hauntingDB.prepareStatement(sqlCommand);
    }

    public static Database init() throws SQLException, ClassNotFoundException{
        if(singletonDB == null){
            singletonDB = new Database();
        }

        return singletonDB;
    }

    public void close(){
        try {
            hauntingDB.close();
        } catch (SQLException e) {
            System.err.println("Cannot close database, or it is already closed: " + e.getMessage());
        }
    }

    public boolean storeAccount(Story hauntingAccount) throws Exception{

        boolean accountStored = false;

        System.err.println("----INSERTING ENTRY----");
        System.err.println("Title: " + hauntingAccount.getTitle());
        System.err.println("Author: " + hauntingAccount.getAuthor());
        if(hauntingAccount.getTitle().length() == 0 || hauntingAccount.getAuthor().length() == 0){
            System.err.println("URL: " + hauntingAccount.getPageURL());
            throw new Exception("TITLE OR AUTHOR IS EMPTY!!!");
        }
        try{
            statement.setString(1, hauntingAccount.getTitle());
            statement.setString(2, hauntingAccount.getAuthor());
            statement.setString(3, hauntingAccount.getStory());
            statement.setString(4, hauntingAccount.getStory().toLowerCase());
            statement.executeUpdate();
            System.err.println("SUCCESS!");
            accountStored = true;
        }
        catch(SQLException e){
            String dbClosed = "UNKNOWN";
            try {
                dbClosed = hauntingDB.isClosed() ? "CLOSED" : "OPEN";
            } catch (SQLException e1) {
                System.err.println("Could not get DB connection state.");
            }
            System.err.println("-------------------------------------------");
            System.err.println("Could not execute SQL insert: " + e.getMessage());
            System.err.println("Error code: " + e.getErrorCode());
            System.err.println("SQL State: " + e.getSQLState());
            System.err.println("DB Connection Status: " + dbClosed);
            e.printStackTrace(System.err);
            System.err.println("Title: " + hauntingAccount.getTitle());
            System.err.println("Author: " + hauntingAccount.getAuthor());
            System.err.println("Page URL: " + hauntingAccount.getPageURL());
            System.err.println("-------------------------------------------");
        }
        finally{
            try {
                SQLWarning warning = statement.getWarnings();
                while (warning != null) {
                    System.err.println("-------------------------------------------");
                    System.err.println("Message: " + warning.getMessage());
                    System.err.print("Error code: " + warning.getErrorCode());
                    System.err.println("SQL State: " + warning.getSQLState());
                    System.err.println("Title: " + hauntingAccount.getTitle());
                    System.err.println("Author: " + hauntingAccount.getAuthor());
                    System.err.println("Page URL: " + hauntingAccount.getPageURL());
                    System.err.println("-------------------------------------------");
                    warning = warning.getNextWarning();
                }
            } catch (SQLException e) {
                // Ignore
            }
        }

        return accountStored;
    }

}

不要使用JDBC/ODBC网桥,因为它速度慢、有缺陷且不推荐使用。改用JDBC驱动程序中的一个命令:@a_horse_,它的名字是“没有”的!非常感谢。