Using KeyedEntity leads to error "Column specified twice" while inserting new row

220 views
Skip to first unread message

chris

unread,
Apr 12, 2011, 5:35:43 AM4/12/11
to Squeryl
Hi,
I'm trying to insert a user into a User table. I'm using
squeryl_2.8.1:0.9.4-RC6
The code looks like the following:

case class User(username: String, password: String, surname: String,
givenname: String, email: Option[String],
phonenumber: Option[String],
isEnabled: Boolean, rolename: String) extends
KeyedEntity[String] {

@Column("username")
val id: String = username

def this() = this("", "", "", "", Some(""), Some(""), false, "")
}

// create the table

val users = table[User]

// insert user

transaction {
users.insert(user)
}

Please note the annotation where I say that the id column's name is
username.
Updating a user works, but when I'm doing the insert, I get the
following exception:

Exception while executing statement : Column 'username' specified
twice
errorCode: 1110, sqlState: 42000
insert into User (email, username, surname, rolename, username,
givenname, isEnabled, phonenumber, password) values (
?,?,?,?,?,?,?,?,?)
java.lang.RuntimeException: Exception while executing statement :
Column 'username' specified twice
errorCode: 1110, sqlState: 42000
insert into User (email, username, surname, rolename, username,
givenname, isEnabled, phonenumber, password) values (
?,?,?,?,?,?,?,?,?)
at org.squeryl.internals.DatabaseAdapter
$class._exec(DatabaseAdapter.scala:324)
at org.squeryl.internals.DatabaseAdapter
$class.exec(DatabaseAdapter.scala:374)
at org.squeryl.adapters.MySQLAdapter.exec(MySQLAdapter.scala:23)
at org.squeryl.internals.DatabaseAdapter
$class.executeUpdateForInsert(DatabaseAdapter.scala:396)
at
org.squeryl.adapters.MySQLAdapter.executeUpdateForInsert(MySQLAdapter.scala:
23)
at org.squeryl.Table$$anonfun$insert$1.apply(Table.scala:53)
at org.squeryl.logging.StackMarker
$.lastSquerylStackFrame(StatisticsListener.scala:52)
at org.squeryl.Table.insert(Table.scala:34)

Obviously, the sql statement contains the column 'username' twice.
Does anybody know what could be the problem here?

Cheers,
Chris

Maxime Lévesque

unread,
Apr 12, 2011, 6:46:33 AM4/12/11
to squ...@googlegroups.com

It looks like a bug, I'm looking into it,

one question : do you want to store both id *and* username ?

You can do this and avoid redundance (note the def) :

case class User(
val username: String, val password: String, val surname: String, val givenname: String, val email: Option[String],
val phonenumber: Option[String], val isEnabled: Boolean, val rolename: String) extends KeyedEntity[String] {

 def id: String = username


 def this() = this("", "", "", "", Some(""), Some(""), false, "")
}

ML

chris

unread,
Apr 12, 2011, 6:57:03 AM4/12/11
to Squeryl
Hi,
thanks for your answer.
I only want to store the username.

Chris

Maxime Lévesque

unread,
Apr 12, 2011, 7:02:07 AM4/12/11
to squ...@googlegroups.com

Then

def id: String = username

 instead of

val id: String = username

will avoid the problem.

ML

chris

unread,
Apr 12, 2011, 7:16:57 AM4/12/11
to Squeryl
I guess I misunderstood your first answer, thanks for the
clarification.
I tried to use the def, but I get a strange exception:

assertion failed: expected return type of CompositeKey on method id
in com.test.User
java.lang.AssertionError: assertion failed: expected return type of
CompositeKey on method id in com.test.User
at scala.Predef$.assert(Predef.scala:91)
at org.squeryl.internals.PosoMetaData.<init>(PosoMetaData.scala:134)
at org.squeryl.View.<init>(View.scala:58)
at org.squeryl.Table.<init>(Table.scala:27)
at org.squeryl.Schema$class.table(Schema.scala:338)

The funny thing is, that I am not using a composite key.

Maxime Lévesque

unread,
Apr 12, 2011, 8:39:23 AM4/12/11
to squ...@googlegroups.com

Can you isolate the part of your Schema that does this and send it ?

chris

unread,
Apr 12, 2011, 11:54:23 AM4/12/11
to Squeryl
Hi,
It happens in line 12 of the schema (I have added a commentary to mark
the line). It's really simple
what I want to achieve here. A user has exactly one role. Between role
and right there is a m:n relationship.

assertion failed: expected return type of CompositeKey on method id
in com.test.User
java.lang.AssertionError: assertion failed: expected return type of
CompositeKey on method id in com.test.User

at scala.Predef$.assert(Predef.scala:91)
at org.squeryl.internals.PosoMetaData.<init>(PosoMetaData.scala:134)
at org.squeryl.View.<init>(View.scala:58)
at org.squeryl.Table.<init>(Table.scala:27)
at org.squeryl.Schema$class.table(Schema.scala:338)
at com.test.UserAdministrationSchema$.table(Schema.scala:11)
at org.squeryl.Schema$class.table(Schema.scala:335)
at com.test.UserAdministrationSchema$.table(Schema.scala:11)
at com.test.UserAdministrationSchema$.<init>(Schema.scala:12)
at com.test.UserAdministrationSchema$.<clinit>(Schema.scala)

object UserAdministrationSchema extends Schema {
val user = table[User] // line 12
val userRoles = table[UserRole]
val userRights = table[UserRight]

val roleToRight = manyToManyRelation(userRoles,
userRights).via[Role_Right](
(role, right, role_right) => (role_right.rolename === role.id,
right.id === role_right.rightname))
}

case class User(@Column("username") username: String, password:
String, surname: String,
givenname: String, email: Option[String],
phonenumber: Option[String],
isEnabled: Boolean, rolename: String) extends
KeyedEntity[String] {

// @Column("username")
def id: String = username

lazy val role = userRoles.where(ur => ur.rolename ===
rolename).single

def this() = this("", "", "", "", Some(""), Some(""), false, "")
}

case class UserRole(rolename: String) extends KeyedEntity[String] {

@Column("rolename")
val id: String = rolename

lazy val rights = UserAdministrationSchema.roleToRight.left(this)
}

case class UserRight(rightname: String) extends KeyedEntity[String] {

@Column("rightname")
val id: String = rightname

lazy val roles = UserAdministrationSchema.roleToRight.right(this)
}

case class Role_Right(rolename: String, rightname: String)
extends KeyedEntity[CompositeKey2[String, String]] {

def id = compositeKey(rolename, rightname)
}

Christian

chris

unread,
Apr 13, 2011, 6:58:27 AM4/13/11
to Squeryl
Hi again,
I avoided the problem by renaming the username field of User to id:

case class User(@Column("username") id: String, password: String,
surname: String,
givenname: String, email: Option[String], phonenumber:
Option[String],
isEnabled: Boolean, rolename: String) extends
KeyedEntity[String] {

lazy val role = userRoles.where(ur => ur.rolename ===
rolename).single

def this() = this("", "", "", "", Some(""), Some(""), false, "")
}

Cheers,
Christian
Message has been deleted

Maxime Lévesque

unread,
Apr 22, 2011, 8:49:21 AM4/22/11
to squ...@googlegroups.com

In Chris's original class, he was defining 2 fields: username and id,
the id field had a column name 'username', so there was a name clash
clash in his definition.
I created a ticket to make sure that an exception with an explanatory message gets thrown when this happens :

  http://www.assembla.com/spaces/squeryl/tickets/45-validate-column-name-uniqueness-in-poso-at-schema-initialization-time#last_comment

So if you have a name clash in your definition, you have to correct this, if
not, please send your class def.

OTOH, Chriss applied this change :


case class User(username: String, password: String, surname: String,
                  givenname: String, email: Option[String],
phonenumber: Option[String],
                  isEnabled: Boolean, rolename: String) extends
KeyedEntity[String] {
 
  def id: String = username

 def this() = this("", "", "", "", Some(""), Some(""), false, "")
}

and got an exception, *this* is a bug :

 http://www.assembla.com/spaces/squeryl/tickets/46--def-id--on-non-composite-keyedentity-backed-by-another-field-causes-assertion-failure

I just pushed a fix for this in the maste branch :

  https://github.com/max-l/Squeryl/commit/60662f00f487f2862dbf900a7afea84cde0bc00e

It will be in the next release (RC7)

ML

On Thu, Apr 21, 2011 at 10:41 PM, debuggr <simo...@gmail.com> wrote:
Hi,

I am seeing the same runtime assertion failure as Chris:

[error] java.lang.AssertionError: assertion failed:  expected return type of CompositeKey on method id in Foobar
[error] at scala.Predef$.assert(Predef.scala:91)
[error] at org.squeryl.internals.PosoMetaData.<init>(PosoMetaData.scala:134)
[error] at org.squeryl.View.<init>(View.scala:58)
[error] at org.squeryl.Table.<init>(Table.scala:27)
[error] at org.squeryl.Schema$class.table(Schema.scala:338)

I too am trying to use a class that extends KeyedEntity[String]; I won't bother pasting my code because it's esssentially the same as above.  I don't want to rename my field to ID.  Is this possibly a bug?

Thanks,
Simon

Reply all
Reply to author
Forward
0 new messages