Note that there are some explanatory texts on larger screens.

plurals
  1. PO"attempt to use a raw table object" error when using a MappedProjection in a query
    text
    copied!<p>I'm trying to figure out how to add a query with a mapped projection in Slick, but no matter what I try I keep coming up against the following error:</p> <pre><code>[error] (run-main) scala.slick.SlickException: Select(TableNode, "USER_NAME") found. This is typically caused by an attempt to use a "raw" table object directly in a query without introducing it through a generator. scala.slick.SlickException: Select(TableNode, "USER_NAME") found. This is typically caused by an attempt to use a "raw" table object directly in a query without introducing it through a generator. at scala.slick.ast.Select.&lt;init&gt;(Node.scala:340) at scala.slick.ast.Select.copy(Node.scala:338) at scala.slick.ast.Select.nodeRebuild(Node.scala:345) at scala.slick.ast.Select.nodeRebuild(Node.scala:338) at scala.slick.ast.UnaryNode$class.nodeRebuild(Node.scala:141) at scala.slick.ast.Select.nodeRebuild(Node.scala:338) at scala.slick.ast.SimpleNode$$anonfun$nodeMapChildren$1.apply(Node.scala:62) at scala.slick.ast.SimpleNode$$anonfun$nodeMapChildren$1.apply(Node.scala:62) at scala.Option.map(Option.scala:145) at scala.slick.ast.SimpleNode$class.nodeMapChildren(Node.scala:62) at scala.slick.ast.Select.nodeMapChildren(Node.scala:338) at scala.slick.compiler.Inline.scala$slick$compiler$Inline$$tr$1(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:38) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:37) at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47) at scala.slick.ast.Node$class.nodeMapNodes(Node.scala:37) at scala.slick.ast.ProductNode$$anon$3.nodeMapNodes(Node.scala:82) at scala.slick.ast.SimpleNode$class.nodeMapChildren(Node.scala:62) at scala.slick.ast.ProductNode$$anon$3.nodeMapChildren(Node.scala:82) at scala.slick.compiler.Inline.scala$slick$compiler$Inline$$tr$1(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:38) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:37) at scala.collection.immutable.List.foreach(List.scala:309) at scala.slick.ast.Node$class.nodeMapNodes(Node.scala:37) at scala.slick.ast.Pure.nodeMapNodes(Node.scala:151) at scala.slick.ast.SimpleNode$class.nodeMapChildren(Node.scala:62) at scala.slick.ast.Pure.nodeMapChildren(Node.scala:151) at scala.slick.compiler.Inline.scala$slick$compiler$Inline$$tr$1(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.compiler.Inline$$anonfun$scala$slick$compiler$Inline$$tr$1$3.apply(Inline.scala:67) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:38) at scala.slick.ast.Node$$anonfun$nodeMapNodes$1.apply(Node.scala:37) at scala.collection.immutable.List.foreach(List.scala:309) </code></pre> <p>I'm new to Scala and Slick and am having difficulty figuring out what the message means. I think it has to do with this (taken from the slick docs):</p> <blockquote> <p>Note that Slick clones your table objects under the covers, so you should not add any extra state to them (extra methods are fine though). Also make sure that an actual object for a table is not defined in a static location (i.e. at the top level or nested only inside other objects) because this can cause problems in certain situations due to an overeager optimization performed by scalac. Using a val for your table (with an anonymous structural type or a separate class definition) is fine everywhere. <a href="http://slick.typesafe.com/doc/1.0.0/lifted-embedding.html" rel="nofollow">Lifted Embedding</a></p> </blockquote> <p>I've modified the slick-examples MultiDBCakeExample to look like the code below and have tried several permutations but with no luck. The code below is taken from my forked version of the <a href="https://github.com/burma-shave/slick-examples" rel="nofollow">slick-examples project</a>. Here is a link to just <a href="https://github.com/burma-shave/slick-examples/commit/eb4c63b4dca2b04898da53b61bb15147c478ff1c" rel="nofollow">my changes</a>.</p> <pre class="lang-scala prettyprint-override"><code>package com.typesafe.slick.examples.lifted import scala.slick.driver.ExtendedProfile import scala.slick.session.Session import scala.slick.driver.H2Driver import scala.slick.driver.SQLiteDriver trait Profile { val profile: ExtendedProfile } case class Picture(url: String, id: Option[Int] = None) trait PictureComponent { this: Profile =&gt; //requires a Profile to be mixed in... import profile.simple._ //...to be able import profile.simple._ object Pictures extends Table[(String, Option[Int])]("PICTURES") { // ^ Table comes from the *current* profile def id = column[Option[Int]]("PIC_ID", O.PrimaryKey, O.AutoInc) def url = column[String]("PIC_URL", O.NotNull) def * = url ~ id val autoInc = url returning id into { case (url, id) =&gt; Picture(url, id) } def insert(picture: Picture)(implicit session: Session): Picture = { autoInc.insert(picture.url) } } } case class User(name: String, picture: Picture, id: Option[Int] = None) case class UserAndPicId(name: String, picId: Int) trait UserComponent { this: Profile with PictureComponent =&gt; //requires Profile and Picture (see def insert) import profile.simple._ object Users extends Table[(String, Int, Option[Int])]("USERS") { def id = column[Option[Int]]("USER_ID", O.PrimaryKey, O.AutoInc) def name = column[String]("USER_NAME", O.NotNull) def pictureId = column[Int]("PIC_ID", O.NotNull) def * = name ~ pictureId ~ id def justNameAndPicId = name ~ pictureId &lt;&gt; (UserAndPicId, UserAndPicId.unapply _) private def autoInc(implicit session: Session) = name ~ pictureId returning id into { case (_, id) =&gt; id } def insert(user: User)(implicit session: Session): User = { val picture = if (user.picture.id.isEmpty) { //if no picture id... Pictures.insert(user.picture) //...insert } else user.picture //else return current picture val id = autoInc.insert(user.name, picture.id.get) user.copy(picture = picture, id = id) } def userAndPicById = for { id &lt;- Parameters[Int] user &lt;- this if user.id === id } yield justNameAndPicId } } /** * The Data Access Layer contains all components and a profile */ class DAL(override val profile: ExtendedProfile) extends UserComponent with PictureComponent with Profile { import profile.simple._ def create(implicit session: Session): Unit = { (Users.ddl ++ Pictures.ddl).create //helper method to create all tables } } /** * Run SLICK code with multiple DBMSs using the Cake pattern. * Typically this technique can be used to have different DBMS * in production and test (other scenarios are possible as well) */ object MultiDBCakeExample { // We only need the DB/session imports outside the DAL import scala.slick.session.{ Database, Session } def run(name: String, dal: DAL, db: Database) { import dal._ import dal.profile.simple._ println("Running test against " + name) db withSession { implicit session: Session =&gt; dal.create //creating our default picture val defaultPic = Pictures.insert(Picture("http://pics/default")) println(" Inserted picture: " + defaultPic) //inserting users val (user1, user2, user3) = (User("name1", defaultPic), User("name2", Picture("http://pics/2")), User("name3", defaultPic)) println(" Inserted user: " + Users.insert(user1)) println(" Inserted user: " + Users.insert(user2)) println(" Inserted user: " + Users.insert(user3)) println(" All pictures: " + Query(Pictures).list) println(" All users : " + Query(Users).list) println(" Attempting to fetch UserAndPicId by id") Users.userAndPicById(1).firstOption } } def main(args: Array[String]) { run("H2", new DAL(H2Driver), Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver")) run("SQLite", new DAL(SQLiteDriver), Database.forURL("jdbc:sqlite::memory:", driver = "org.sqlite.JDBC")) } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload