Can't navigate two or more level deeper in associations within a query
I created the following model clases (I will obviate the imports):
case class Event(description:String, guests:Int, budget:Float, var date: Option[Date] = None) extends ActiveRecord { lazy val reservations = hasMany[Reservation]
def addReservation(reservation: Reservation) = {
val serviceId = reservation.service.id
if(reservations.exists(x => x.service.id === serviceId))
throw new Exception()
reservations << reservation
}
}
object Event extends ActiveRecordCompanion[Event] with PlayFormSupport[Event]
case class Reservation(date: Date, price: Float) extends ActiveRecord { val serviceId: Option[Long] = None lazy val service = belongsTo[Service]
val eventId: Option[Long] = None
lazy val event = belongsTo[Event]
}
object Reservation extends ActiveRecordCompanion[Reservation] with PlayFormSupport[Reservation]
case class Service(description: String, price: Float) extends ActiveRecord { lazy val reservations = hasMany[Reservation] }
object Service extends ActiveRecordCompanion[Service] with PlayFormSupport[Service]
object Tables extends ActiveRecordTables with PlaySupport { val services = table[Service] val events = table[Event] val reservations = table[Reservation] }
Then I have created this dummy test:
object UserSpec extends ActiveRecordPlaySpecification {
override def beforeAll = {
super.beforeAll
}
"The Event" should {
"add a reservation" >> {
val service = Service("El mejor salon", 10f)
service.create
val event = Event("my birthday", 100, 1000.50f)
event.save
val confirmationDate = new Date()
var reservation = Reservation(confirmationDate, 10.0f)
reservation.service := service
reservation.save
event.addReservation(reservation)
event.date must equalTo(None)
}
}
} When I run this test I get the following error:
[info] UserSpec [info] The Event should [info] ! add a reservation [error] ClassNotFoundException: models.Reservation$$EnhancerByCGLIB$$326b16c 6$ (null:-1) [error] sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$class.loadClas s(reflections.scala:192) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$.loadClass(ref lections.scala:281) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$class.classToC ompanion(reflections.scala:201) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$.classToCompan ion(reflections.scala:281) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$class.classToC ompanion(reflections.scala:210) [error] com.github.aselab.activerecord.reflections.ReflectionUtil$.classToCompan ion(reflections.scala:281) [error] com.github.aselab.activerecord.inner.ProductModel$class._companion(Produ ctModel.scala:10) [error] com.github.aselab.activerecord.ActiveRecord._companion$lzycompute(Active Record.scala:73) [error] com.github.aselab.activerecord.ActiveRecord._companion(ActiveRecord.scal a:73) [error] models.Reservation$$EnhancerByCGLIB$$326b16c6.CGLIB$_companion$39() [error] models.Reservation$$EnhancerByCGLIB$$326b16c6$$FastClassByCGLIB$$ae6b4fc 1.invoke() [error] net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:215) [error] org.squeryl.internals.FieldReferenceLinker$PosoPropertyAccessInterceptor ._intercept(FieldReferenceLinker.scala:322) [error] org.squeryl.internals.FieldReferenceLinker$PosoPropertyAccessInterceptor .intercept(FieldReferenceLinker.scala:309) [error] models.Reservation$$EnhancerByCGLIB$$326b16c6._companion() [error] com.github.aselab.activerecord.inner.Associations$BelongsToAssociation.f oreignKeyInfo$lzycompute(Associations.scala:84) [error] com.github.aselab.activerecord.inner.Associations$BelongsToAssociation.f oreignKeyInfo(Associations.scala:84) [error] com.github.aselab.activerecord.inner.Associations$BelongsToAssociation$$ anonfun$condition$1.apply(Associations.scala:87) [error] com.github.aselab.activerecord.inner.Associations$BelongsToAssociation$$ anonfun$condition$1.apply(Associations.scala:87) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$wra p$1.apply(Relations.scala:115) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1$$anonfun$apply$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1$$anonfun$apply$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1.apply(Relations.scala:82) [error] org.squeryl.dsl.fsm.BaseQueryYield$$anonfun$whereClause$1.apply(BaseQuer yYield.scala:63) [error] org.squeryl.dsl.fsm.BaseQueryYield$$anonfun$whereClause$1.apply(BaseQuer yYield.scala:63) [error] org.squeryl.dsl.fsm.BaseQueryYield.whereClause(BaseQueryYield.scala:63) [error] org.squeryl.dsl.fsm.BaseQueryYield.queryElements(BaseQueryYield.scala:71 ) [error] org.squeryl.dsl.ast.QueryExpressionNode.(QueryExpressionNode.scala :36) [error] org.squeryl.dsl.AbstractQuery.buildAst(AbstractQuery.scala:103) [error] org.squeryl.dsl.boilerplate.Query1.(Query1.scala:34) [error] org.squeryl.dsl.boilerplate.FromSignatures$class.from(FromSignatures.sca la:25) [error] com.github.aselab.activerecord.dsl$.from(packages.scala:6) [error] com.github.aselab.activerecord.inner.Relations$Relation1.toQuery(Relatio ns.scala:335) [error] com.github.aselab.activerecord.inner.Relations$Relation$class.toQuery(Re lations.scala:318) [error] com.github.aselab.activerecord.inner.Relations$Relation1.toQuery(Relatio ns.scala:325) [error] com.github.aselab.activerecord.inner.Relations$Relation$$anonfun$headOpt ion$1.apply(Relations.scala:203) [error] com.github.aselab.activerecord.inner.Relations$Relation$$anonfun$headOpt ion$1.apply(Relations.scala:203) [error] org.squeryl.dsl.QueryDsl$class.inTransaction(QueryDsl.scala:147) [error] com.github.aselab.activerecord.dsl$.inTransaction(packages.scala:6) [error] com.github.aselab.activerecord.inner.Relations$Relation$class.headOption (Relations.scala:203) [error] com.github.aselab.activerecord.inner.Relations$Relation1.headOption(Rela tions.scala:325) [error] com.github.aselab.activerecord.inner.Relations$Relation$class.head(Relat ions.scala:198) [error] com.github.aselab.activerecord.inner.Relations$Relation1.head(Relations. scala:325) [error] com.github.aselab.activerecord.inner.DSL$class.belongsToAssociationToRec ord(Implicits.scala:49) [error] com.github.aselab.activerecord.dsl$.belongsToAssociationToRecord(package s.scala:6) [error] models.Event$$anonfun$addReservation$1.apply(Event.scala:14) [error] models.Event$$anonfun$addReservation$1.apply(Event.scala:14) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$wra p$1.apply(Relations.scala:115) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1$$anonfun$apply$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1$$anonfun$apply$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1.apply(Relations.scala:82) [error] com.github.aselab.activerecord.inner.Relations$QuerySupport$$anonfun$whe reScope$1.apply(Relations.scala:82) [error] org.squeryl.dsl.fsm.BaseQueryYield$$anonfun$whereClause$1.apply(BaseQuer yYield.scala:63) [error] org.squeryl.dsl.fsm.BaseQueryYield$$anonfun$whereClause$1.apply(BaseQuer yYield.scala:63) [error] org.squeryl.dsl.fsm.BaseQueryYield.whereClause(BaseQueryYield.scala:63) [error] org.squeryl.dsl.fsm.MeasuresQueryYield.queryElements(BaseQueryYield.scal a:147) [error] org.squeryl.dsl.ast.QueryExpressionNode.(QueryExpressionNode.scala :36) [error] org.squeryl.dsl.AbstractQuery.buildAst(AbstractQuery.scala:103) [error] org.squeryl.dsl.boilerplate.Query1.(Query1.scala:34) [error] org.squeryl.dsl.boilerplate.FromSignatures$class.from(FromSignatures.sca la:25) [error] com.github.aselab.activerecord.dsl$.from(packages.scala:6) [error] com.github.aselab.activerecord.inner.Relations$Relation1.toQuery(Relatio ns.scala:335) [error] com.github.aselab.activerecord.inner.Relations$Relation$class.count(Rela tions.scala:282) [error] com.github.aselab.activerecord.inner.Relations$Relation1.count(Relations .scala:325) [error] com.github.aselab.activerecord.inner.Relations$Relation$$anonfun$exists$ 1.apply$mcZ$sp(Relations.scala:276) [error] com.github.aselab.activerecord.inner.Relations$Relation$$anonfun$exists$ 1.apply(Relations.scala:276) [error] com.github.aselab.activerecord.inner.Relations$Relation$$anonfun$exists$ 1.apply(Relations.scala:276) [error] org.squeryl.dsl.QueryDsl$class.inTransaction(QueryDsl.scala:147) [error] com.github.aselab.activerecord.dsl$.inTransaction(packages.scala:6) [error] com.github.aselab.activerecord.inner.Relations$Relation$class.exists(Rel ations.scala:275) [error] com.github.aselab.activerecord.inner.Relations$Relation1.exists(Relation s.scala:325) [error] models.Event.addReservation(Event.scala:14) [error] UserSpec$$anonfun$1$$anonfun$apply$1.apply(UserSpec.scala:63) [error] UserSpec$$anonfun$1$$anonfun$apply$1.apply(UserSpec.scala:47) [info] Total for specification UserSpec [info] Finished in 1 second, 447 ms [info] 1 example, 0 failure, 1 error [error] Error: Total 1, Failed 0, Errors 1, Passed 0 [error] Error during tests: [error] UserSpec error sbt.TestsFailedException: Tests unsuccessful [error] Total time: 7 s, completed 20/03/2014 13:06:43 [active-record] $ [active-record] $
I don´t know if I make some mistake or is a bug in Scala Activerecord. This error only happens when I try to navigate two or more level deeper in associations, like the line:
reservations.exists(x => x.service.id === serviceId)
I know that in this case I can use x.serviceId but It is a problem if I need filter with the service description, like this:
reservations.exists(x => x.service.description === description)
There is any limitation with the deeper level that I can use when we query through an association??
Thanks
It's not possible to use associations in query DSL.
reservations.exists(x => x.service.description === description)
In this case, you should query by Service side.
val serviceIds = reservations.select(_.serviceId).toList.flatten
Service.exists(service => service.id in serviceIds and service.description === description)