Derby 和 Circumflex ORM 的 SQL 语法错误

Posted

技术标签:

【中文标题】Derby 和 Circumflex ORM 的 SQL 语法错误【英文标题】:SQL syntax error with Derby and Circumflex ORM 【发布时间】:2010-06-24 20:20:33 【问题描述】:

我正在尝试使用 Circumflex ORM(如 *** 上的建议 - here、here 和 here)通过 JDBC 从 Scala 项目(用简单的构建工具)。我已仔细按照说明进行操作,但遇到了一些有趣的问题。

这是 cx.properties 文件的驱动程序和 URL 组件:

orm.connection.driver=org.apache.derby.jdbc.EmbeddedDriver
orm.connection.url=jdbc:derby:derbyDB

(这些映射到使用原始 JDBC 或persistence.xml 中的等价物的“反射驱动程序的实例创建并创建连接”模型 - Circumflex 正在使用一个简短而甜蜜的属性文件,因为您知道,它不是 XML 和这是一件好事。)

我在我的 sbt 项目文件中添加的直接相关的依赖项是:

  "ru.circumflex" % "circumflex-orm" % "1.0",
  "org.apache.derby" % "derby" % "10.6.1.0"

我创建了一个简短的示例模型,它定义了文档描述的表格的简化版本:

import java.sql.DriverManager
import ru.circumflex.orm._

class Country extends Record[Country] 
  val code = "code" VARCHAR(2)
  val name = "name" TEXT


object Country extends Table[Country]

这似乎可以编译,我可以实例化 Country 对象(使用通过 sbt 控制台调用的 Scala 2.8.0 RC5 shell)并创建一个 ActiveRecord 样式的对象,然后像这样保存它:

val c = new Country
c.code := "US"
c.name := "United States of America"
c.save

根据文档,这应该对对象运行验证,然后将其插入数据库。我得到以下异常:

java.sql.SQLSyntaxErrorException: Syntax error: Encountered "public" at line 1, column 13.
        at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement30...

我发现 this thread 有人在 'Encountered "public"' 和 Apache Derby 方面遇到类似问题,但回复似乎没有提出有用的前进方式。

任何想法可能导致这种情况?

【问题讨论】:

很抱歉,如果这不是一个特别有趣的问题 - 在被 Rails 的 ActiveRecord 实现的开箱即用的纯粹简单性宠坏之后,我仍然在 Javaland 中找到自己的方式。有人告诉我 Circumflex ORM 很烂,我愿意选择别的东西。 【参考方案1】:

您可能需要明确告诉 Circumflex 使用 Derby 语法,而不是期望它是从 JDBC 驱动程序类名和 URL 推断出来的。

例如在 Hibernate 中你需要设置方言...

您似乎可以通过将"orm.defaultSchema" property 设置为“public”以外的值来解决这个问题,这在德比中似乎是reserved word。

而且,最后的编辑,大多数时候人们在创建表时不会费心使用显式模式名称,他们只是获得默认值,但 Circumflex 似乎总是添加它,所以对于 Derby,你应该能够使用“APP”作为架构名称,或预先创建自己的架构并使用其名称。

【讨论】:

感谢 Alex 的这一点以及对 IRC 的帮助。 Dialect trait 也有 supportsSchema_?() 方法——你可以在你的方言中覆盖它,Circumflex 会忘记显式模式。永远。【参考方案2】:

我一直在使用带有 Hypersonic 的 Circumflex ORM。它默认只支持 Postgres、mysql 和 Oracle。您需要扩展 ru.circumflex.orm.Dialect 以为 Derby 提供正确的 SQL 语法,并在 cx.properties 文件中声明此类。即

orm.dialect=com.magmanics.circumflex.orm.dialect.HsqldbDialect

这是我的 Hypersonic 方言文件,如果您只是在寻找一个简单的内存数据库,它可能会对您有所帮助...

import ru.circumflex.orm._

/**
 * @author James Baxter <j.w.baxter(at)gmail>
 * @since 19-Jun-2010
 */
class HsqldbDialect extends Dialect 

  override def timestampType = "TIMESTAMP"
  override def createSchema(schema: Schema) = "CREATE SCHEMA " + schema.name + " AUTHORIZATION DBA"
  override def createTable(table: Table[_]) = "CREATE TABLE " + table.qualifiedName + " (" + table.fields.map(_.toSql).mkString(", ") + ")"
  override def columnDefinition(field: Field[_]): String = 
    var result = field.name + " " + field.sqlType
    field.default match 
      case Some(expr) => result += " " + expr
      case _ =>
    
    if (!field.nullable_? && !result.contains("PRIMARY KEY")) result += " NOT NULL"
    return result
  
  override def primaryKeyExpression(record: Record[_]) = "IDENTITY PRIMARY KEY"
  override def initializeRelation(relation: Relation[_]) = 
  override def lastIdExpression(node: RelationNode[_]) = node.alias + "." + node.relation.primaryKey.name + " = IDENTITY()"

【讨论】:

去吧。感谢您创建了如此出色的框架,很高兴能够为它做出贡献:)

以上是关于Derby 和 Circumflex ORM 的 SQL 语法错误的主要内容,如果未能解决你的问题,请参考以下文章

LibreOffice Writer 中字母上方的帽子 / circumflex

什么是最简单的Java ORM支持Sqlite?

如何连接 Derby 数据库和 Servlet?

德比和日食。 “找不到主要”异常。如何将 Derby 添加到配置类路径?

使用 derby 数据库和 netbeans ide 创建触发器

Apache Derby-02通过IJ简单操作DERBY