我正在尝试使用Circumflex ORM(如StackOverflow建议 - here,here和here)来连接本地(嵌入式)Apache Derby数据库来自Scala项目的JDBC(使用简单的构建工具构建)。我仔细按照说明操作,但遇到了一些有趣的问题。
以下是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某人遇到类似“遇到的”公共“和Apache Derby”的问题,但这些回复似乎并没有提出一个有用的方法。
任何可能导致此问题的想法?
答案 0 :(得分:5)
您可能需要告诉Circumflex显式使用Derby语法,而不是期望从JDBC驱动程序类名和URL推断它。
e.g。在Hibernate中你需要设置方言......
似乎你可以通过将"orm.defaultSchema" property设置为“公共”以外的其他东西来解决这个问题,这似乎是德比中的reserved word。
而且,最终编辑,大多数时候人们在创建表时都不打算使用显式模式名称,而且他们只是得到默认值,但Circumflex似乎总是添加它,所以对于Derby,你应该能够使用“APP”作为模式名称,或事先创建自己的模式并使用其名称。
答案 1 :(得分:2)
我一直在使用Circumflex ORM和Hypersonic。它默认只支持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()"
}
/**
* @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()"
}