Jdbc 此数据库不支持getGeneratedKeys功能

Jdbc 此数据库不支持getGeneratedKeys功能,jdbc,spring-jdbc,sqlanywhere,Jdbc,Spring Jdbc,Sqlanywhere,我正在运行SQLAnywhere 16.0,并尝试使用SpringJDBC模板。我需要做的非常简单:在表中插入一行,然后返回自动生成的ID值 public int log() { SimpleJdbcInsert insertActor = new SimpleJdbcInsert(ds) .withTableName("DBA.REQUESTS") .usingGeneratedKeyColumns("REQUE

我正在运行SQLAnywhere 16.0,并尝试使用SpringJDBC模板。我需要做的非常简单:在表中插入一行,然后返回自动生成的ID值

public int log() {
    SimpleJdbcInsert insertActor = 
            new SimpleJdbcInsert(ds)
            .withTableName("DBA.REQUESTS")
            .usingGeneratedKeyColumns("REQUEST_ID");

    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("USER_ID", userId);
    parameters.put("DATA_TYPE_ID", getProductSku());
    parameters.put("PRICE", price);
    // ...more parameters

    Number requestIdNumber = insertActor.executeAndReturnKey(parameters);
    return requestIdNumber.intValue();
}
我正在使用的驱动程序应该支持JDBC4.0。库是dbjdbc16.dll,它位于路径中,sajdbc4.jar位于Tomcat lib目录中。来自Tomcat的相关数据库连接信息是

    <Resource auth="Container" description="Pooled connection to the web database" 
    driverClassName="sybase.jdbc4.sqlanywhere.IDriver" 
    maxActive="30" maxIdle="5" maxWait="10000" name="jdbc/web" 
    removeAbandoned="true" 
    removeAbandonedTimeout="60" 
    type="javax.sql.DataSource" 
    url="jdbc:sqlanywhere:Server=web;UID=xxx;PASSWORD=xxx;port=xxxx;LINKS=tcpip(PORT=xxxx)"/>
数据源的Spring应用程序上下文是

<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/web"
            expected-type="javax.sql.DataSource" />  
所以我的问题是,有没有一种方法可以更好地进行配置,从而使这种类型的语句能够工作? 或者,如果数据库在某些基本层面上确实不支持这一点,那么是否有一种非难看的替代方法可以让我插入值并返回生成的id

更新:数据库驱动程序似乎不支持此功能。这里和其他地方的建议是插入,而不是紧接着选择。当然,问题是如果另一个用户在这两个语句之间插入表,您将得到错误的值,在这种情况下,这将非常糟糕


我现在的解决方法是在相关的DAO上使用类级锁,并基于多个列(而不仅仅是标识)进行选择,这样我就可以99.9%确定返回的是同一行。它足够好用了。也就是说,我更喜欢使用事务方式锁定表。我不认为将函数标记为@Transactional会起作用,对吧,因为这只会延迟提交,直到所有语句都成功为止?

我根本不是JDBC专家,所以我不能直接回答这个问题,但我可以告诉你,SQL Anywhere服务器确实具有这种能力。如果JDBC的东西不起作用,可以使用变量。正在获取select@@identity,它将返回最后一条语句的自动生成值


免责声明:我在SQL Anywhere engineering中为SAP工作。

有帮助吗?不,不幸的是,这正是我所做的。您的驱动程序支持返回生成的密钥吗?这是JDBC 4.0规范中的一个可选功能。您可以通过使用DatabaseMetaData.supportsGetGeneratedKeys方法检查JDBC数据库元数据来确定它是否存在。Ah-可选功能-解释了它。这个方法给出的答案是否定的,这就是为什么Spring显示错误的原因。谢谢Graeme!不幸的是,这不包括其他用户在运行select之前执行了insert的情况。如果他们有,你会得到错误的值,在这种情况下,这将是非常糟糕的。如果有一种JDBC方法在完成选择之前锁定表,那将是理想的。不,不是这样。抱歉,我的描述不完整-选择@@identity返回在当前连接上完成的最后一个insert语句的自动生成值。因此,如果您的连接插入一行,然后另一个连接插入一行,请在连接上选择@@identity返回您插入的行的id。非常有趣。不过我使用的是一个连接池——我认为两个用户可能会共享一个连接,除非有某种方法可以防止这种情况发生?
<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/web"
            expected-type="javax.sql.DataSource" />