Spring Postgres没有错误,也没有插入

Spring Postgres没有错误,也没有插入,spring,postgresql,jdbc,spring-boot,Spring,Postgresql,Jdbc,Spring Boot,目前,我正在使用PostgresJDBC驱动程序在SpringBoot中工作,并且我已经与我的数据库建立了连接。然而,第一次尝试插入时,我没有收到任何错误,但在DB端,我没有看到任何插入。在第二次尝试时,我得到以下错误: Cannot get out of auto-commit mode with error: org.postgresql.util.PSQLException: This connection has been closed. SQLException: org.postgr

目前,我正在使用PostgresJDBC驱动程序在SpringBoot中工作,并且我已经与我的数据库建立了连接。然而,第一次尝试插入时,我没有收到任何错误,但在DB端,我没有看到任何插入。在第二次尝试时,我得到以下错误:

Cannot get out of auto-commit mode with error: org.postgresql.util.PSQLException: This connection has been closed.
SQLException: org.postgresql.util.PSQLException: This connection has been closed.
在两次尝试中,我都无法插入。我的调试器告诉我已发送以下内容:

preparedStatement: INSERT INTO event (StartTime, EndTime, Description, name, DisplayPicLoc, attendenceCount) VALUES ('2016-2-29 19:0:0.000000 -5:0:0','2016-3-1 19:0:0.000000 -5:0:0','b','b',NULL,0)
我设置的数据库架构如下:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE event (eventID UUID DEFAULT uuid_generate_v4() NOT NULL primary key,
                   StartTime timestamp NOT NULL,
                   EndTime timestamp NOT NULL,
                   Description varchar(1500),
                   name  varchar(80) NOT NULL,
                   DisplayPicLoc varchar(80),
                   attendenceCount int);
我的java服务器端代码如下所示:

@Controller
public class CalendarController {
    @RequestMapping(value="/event", method=RequestMethod.POST)
    public @ResponseBody
    String uploadEvent(@RequestParam("title") String title,
                       @RequestParam("description") String description,
                       @RequestParam("start") Date start,
                       @RequestParam("end") Date end){

    Timestamp startTime = null;
    Timestamp endTime = null;

    try{
        startTime = new Timestamp(start.getTime());
        endTime = new Timestamp(end.getTime());
    }
    catch(Exception e){
        System.err.print("Date conversion error: " + e);
        return "failure";
    }

    System.out.println("Event received with Title: " + title +
            " Description: " + description +
            " Start: " + startTime +
            " End: " + endTime);

    Savepoint savepoint = null;
    Connection connection = DatabaseConnection.connection;
    try{
        connection.setAutoCommit(false);
    }
    catch(SQLException e){
        System.err.println("Cannot get out of auto-commit mode with error: " + e);
    }
    if(connection==null){
        new DatabaseConnection();
    }
    try{
        savepoint = connection.setSavepoint();
        String query = "INSERT INTO event " +
                "(StartTime, EndTime, Description, name, DisplayPicLoc, attendenceCount) " +
                "VALUES (?,?,?,?,?,?);";
        PreparedStatement preparedStatement = connection.prepareStatement(query);
        preparedStatement.setTimestamp(1, startTime);
        preparedStatement.setTimestamp(2, endTime);
        preparedStatement.setString(3, description);
        preparedStatement.setString(4, title);
        preparedStatement.setString(5, null);
        preparedStatement.setInt(6, 0);

        System.out.println("preparedStatement: " + preparedStatement);

        preparedStatement.executeUpdate();
        //connection.close();
        return "success";
    }
    catch(SQLException e){
        System.err.println("SQLException: " + e);
        if(connection!=null && savepoint!=null){
            try{
                connection.rollback(savepoint);
            }
            catch(SQLException error){
                System.err.println("SQLException: " + error);
            }
        }
    }
    finally{
        if(connection != null) {
            try {
                connection.close();
            }
            catch(SQLException e) {
                System.err.println("SQLException: " + e);
            }
        }
    }
    return "failure";
}
}


我哪里出错了?

我的建议是使用连接池,而不是在所有类和线程之间静态共享单个连接。
我不打算详细介绍连接池如何工作以及如何在项目中配置它。SO和互联网上提供了大量优秀的答案和教程。
您可以从这里开始:
这里:




PostgreSQL驱动程序有自己的连接轮询实现,请研究此链接以了解详细信息:
我猜您的应用程序正在某个容器(Tomcat?JBoss?等)中运行。如果是,则几乎所有web容器都有自己的连接池实现
如果为n,则可以使用或库。


简言之,连接池大大简化了与创建和关闭数据库连接相关的所有任务。在所有需要连接的地方,模式都是相同的:

  • 从池(数据源)获取连接
  • 打开或关闭自动提交(取决于需要)
  • 执行一些数据库操作(插入、更新、选择-无论什么)
  • 执行提交(仅当自动提交已关闭时)
  • 关闭电源
  • 关闭连接(将其返回池)
如果您使用的是Java 7,则可以使用try with resources进一步简化代码(连接和准备好的语句将自动关闭):


在你的代码中没有
commit()
你能给我们展示一下
DatabaseConnection
类的代码吗,特别是如何
DatabaseConnection.connection是否已声明和初始化?它看起来像是在不同线程之间共享的静态变量。为什么不使用连接池?@a_horse_和_no_name我应该把commit()放在哪里?我已经在网上查过了,但我不确定我是否理解。@kordirko我的连接是在不同的类之间静态共享的。我不知道什么是连接池。
String query = "INSERT INTO event " +
                "(StartTime, EndTime, Description, name, DisplayPicLoc, attendenceCount) " +
                "VALUES (?,?,?,?,?,?);";
try( Connection conn = DataSource.getConnection();
     PreparedStatement ps = conn.prepareStatement( query ) ){
       ps.setTimestamp(1, startTime);
       ....
       ....
       ps.setInt(6, 0);
       ps.executeUpdate();
       return true; // success
} catch( SQLException e ){
   System.err.println("SQLException: " + e);
   return false; // failure
}