简体   繁体   中英

SQL syntax error with Derby and Circumflex ORM

I'm trying to use Circumflex ORM (as suggested on StackOverflow - here , here and here ) to connect to a local (embedded) Apache Derby database over JDBC from a Scala project (built with simple build tool). I've followed the instructions carefully, but am having some interesting problems.

Here's the driver and URL components of the cx.properties file:

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

(These map to the "instance creation of the reflected driver and create Connection" model with raw JDBC, or the equivalents in persistence.xml - Circumflex is using a short and sweet properties file because, you know, it's not XML and that's a good thing.)

The dependencies I've added in my sbt project file that are directly relevant are:

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

I have created a short example model which defines a simplified version of the table that the documentation describes:

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]

This seems to compile okay, and I can instantiate the Country object (using a Scala 2.8.0 RC5 shell invoked with sbt console) and create an object ActiveRecord-style and then save it like this:

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

According to the documentation, this should run a validation over the object and then insert it into the database. I get the following exception:

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...

I found this thread where someone is having a similar problem with 'Encountered "public"' and Apache Derby, but the replies don't seem to suggest a useful way of going forward.

Any ideas what might be causing this?

It's possible you need to tell Circumflex to use Derby syntax explicitly, instead of expecting it to be inferred from the JDBC driver classname and URL.

eg in Hibernate you need to set the dialect...

And it seems you can work around it by setting the "orm.defaultSchema" property to something other than "public", which seems to be a reserved word in Derby.

And, final edit, most of the time people don't bother to use an explicit schema name when creating tables, and they just get the default, but Circumflex seems to always add it, so for Derby, you should be able to use "APP" as the schema name, or create your own schema beforehand and use its name.

I've been using Circumflex ORM with Hypersonic. It only supports Postgres, MySql and Oracle by default. You need to extend ru.circumflex.orm.Dialect to supply the correct SQL syntax for Derby, and declare this class in your cx.properties file. ie

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

Here is my Hypersonic dialect file, it might help you if you are just looking for a simple in memory database...

import ru.circumflex.orm._

 /** * @author James Baxter <jwbaxter(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()" } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM