【问题标题】:ActiveJDBC has SQLSyntaxErrorExceptionActiveJDBC 有 SQLSyntaxErrorException
【发布时间】:2022-01-05 10:13:40
【问题描述】:

使用 ActiveJDBC,我一直在手动打开和关闭连接,插入和读取任何内容,都没有出现这样的错误:

public class DatabaseLoader {

    private static final Logger logger = LogManager.getLogger(DatabaseLoader.class);

    public static void openConnection() {
        Base.open("com.mysql.cj.jdbc.Driver", ConfigManager.getAddress(), ConfigManager.getUsername(), ConfigManager.getPassword());
    }

    public static void openConnectionIfClosed() {

        if (!Base.hasConnection()) {
            logger.info("Connecting to database!");
            openConnection();
        }
    }

    public static void closeConnectionIfOpen() {
        if (Base.hasConnection()) {
            logger.info("Disconnecting from database!");
            Base.close();
        }
    }
}

但是,我最近尝试添加 C3P0 和连接池,尽可能紧跟 https://github.com/javalite/javalite/blob/master/activejdbc/src/test/java/org/javalite/activejdbc/C3P0PoolTest.java。新代码如下所示:

public class DatabaseLoader {

    private static final Logger logger = LogManager.getLogger(DatabaseLoader.class);

    static DataSource dataSourceUnpooled;
    static DataSource dataSourcePooled;

    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            dataSourceUnpooled = DataSources.unpooledDataSource(ConfigManager.getAddress(), ConfigManager.getUsername(), ConfigManager.getPassword());
            dataSourcePooled = DataSources.pooledDataSource(dataSourceUnpooled); //init the connection pool
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void openConnection() {
        Base.open(dataSourcePooled);
    }

    public static void openConnectionIfClosed() {
        if (!Base.hasConnection()) {
            openConnection();
        }
    }

    public static void closeConnectionIfOpen() {
        if (Base.hasConnection()) {
            logger.info("Disconnecting from database!");
            Base.close();
        }
    }
}

使用此代码,与数据库的初始连接似乎成功并且一切正常,直到我插入一些东西。例如,像这样:

// ServerMessage is an activejdbc model that has worked to insert things 31k times before adding C3P0

ServerMessage message = ServerMessage.findOrCreateIt("message_id_snowflake", messageIdSnowflake, "server_id", serverId, "user_id", userId);

每当我插入一些东西时,我现在都会收到这个错误:

org.javalite.activejdbc.DBException: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '::BIGINT,19::INT,1772::INT)' at line 1, query: INSERT INTO server_messages (message_id_snowflake, server_id, user_id) VALUES (?::BIGINT,?::INT,?::INT), params: 928224895626793001, 19, 1772
        at org.javalite.activejdbc.DB.execInsert(DB.java:734)
        at org.javalite.activejdbc.Model.insert(Model.java:2741)
        at org.javalite.activejdbc.Model.save(Model.java:2673)
        at org.javalite.activejdbc.Model.saveIt(Model.java:2597)
        at org.javalite.activejdbc.ModelDelegate.createIt(ModelDelegate.java:146)
        at org.javalite.activejdbc.ModelDelegate.findOrCreateIt(ModelDelegate.java:438)
        at org.javalite.activejdbc.ModelDelegate.findOrCreateIt(ModelDelegate.java:412)
        at dev.laarryy.eris.models.guilds.ServerMessage.findOrCreateIt(ServerMessage.java:219)
        at dev.laarryy.eris.listeners.MessageCreateListener.on(MessageCreateListener.java:49)
        ... 21 more
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '::BIGINT,19::INT,1772::INT)' at line 1
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1348)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:1502)
        at org.javalite.activejdbc.DB.execInsert(DB.java:713)
        ... 29 more

这对我来说似乎很奇怪,因为应该插入的 bigint、int 和 int 确实是需要的 bigint、int 和 int,我不知道我还能做些什么来找到原因错误。堆栈跟踪倒数第二行的 C3P0 行让我认为 ActiveJDBC 准备的语句在某种程度上不是进入数据库的语句。

我也已经尝试过启用 C3P0 语句缓存,以防万一,但它没有。

任何建议或指导将不胜感激!

更新

我现在也尝试按照此处https://www.mchange.com/projects/c3p0/#quickstart 的快速启动过程进行操作,希望手动设置驱动程序类可以解决问题,但事实并非如此。我仍然得到相同的堆栈跟踪。我试过的代码:

public class DatabaseLoader {

    private static final Logger logger = LogManager.getLogger(DatabaseLoader.class);

    static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();

    static {
        try {
           comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
            comboPooledDataSource.setJdbcUrl(ConfigManager.getAddress());
            comboPooledDataSource.setUser(ConfigManager.getUsername());
            comboPooledDataSource.setPassword(ConfigManager.getPassword());
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
    }

    public static void openConnection() {
        Base.open(comboPooledDataSource);
    }

    public static void openConnectionIfClosed() {
        if (!Base.hasConnection()) {
            openConnection();
        }
    }

    public static void closeConnectionIfOpen() {
        if (Base.hasConnection()) {
            logger.info("Disconnecting from database!");
            Base.close();
        }
    }
}

我也尝试切换到 Hikari 版本 5,但我得到完全相同的错误,除了倒数第二行来自 Hikari 而不是 c3p0。这让我相信 ActiveJDBC 端而不是连接池端出了点问题。

要求的详细信息:

  • Java 版本 17.0.1(修正版)
  • ActiveJDBC 版本 3.0-SNAPSHOT
  • MySQL 版本 8.0.26
  • mysql-connector-java 版本 8.0.26(Driver.getMajorVersion() 返回 8,#getMinorVersion() 也如预期返回 0)
  • C3P0 版本 0.9.5.5

【问题讨论】:

  • 由于某种原因,它试图使用 Postgres 风格的强制转换运算符 ::BIGINT,从而导致错误。
  • 您是否也更改了 JDBC 驱动程序? @Kayaman 似乎提到您的语法看起来像 PostgreSQL。请在您的问题中添加以下内容:Java 版本、JavaLite 版本、数据库和版本以及 JDBC 驱动程序及其版本
  • @ipolevoy 我已经添加了您要求的详细信息 - 如果我遗漏了什么或者您想添加任何内容,请告诉我!

标签: java mysql c3p0 activejdbc


【解决方案1】:

不幸的是,发布了几个小时的有缺陷的快照。该快照 v 3.0-SNAPSHOT 有一个错误,即意外地将 PostgreSQL 语法设为 MySQL 的默认值。它似乎给你带来了问题。 JDBC 连接池与此无关。我们对快照很小心,但这样的事情会发生(几年一次)。你在更新过程中遇到了不幸。

解决此问题的方法是清除所有 Maven 缓存:

rm -rf ~/.m2/repository/org/javalite

在下一次构建中,您将获得一个没有此缺陷的新(大大改进:))快照。

很抱歉给您带来了麻烦,但快照“正在进行中”。

相关错误:https://github.com/javalite/javalite/issues/1187

【讨论】:

  • 谢谢!万一其他人像我一样使用 gradle,运行./gradlew build --refresh-dependencies,也有同样的效果。
  • To 可能想支持这个答案 ;)
  • 我需要收集更多代表 - 我现在已经将其标记为答案,我可以做到
  • 这很好解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多