many to many problem

16 views
Skip to first unread message

Tim Pigden

unread,
Aug 19, 2013, 12:08:08 PM8/19/13
to mapp...@googlegroups.com
Can't see what I'm doing wrong here:

I'm getting this trace message:

16:52:29.317 [specs2.DefaultExecutionStrategy1] DEBUG com.googlecode.mapperdao.jdbc.Jdbc - sql:
select id
from dw.plan_version 
where plan_id = 2
sample plan should

An error occured during select of entity PlanEntity$(Plan,com.optrak.bi.etl.Projects$Plan) and primary keys List(2)
key not found: EntityType(PlanVersion)
com.googlecode.mapperdao.exceptions.QueryException: An error occured during select of entity PlanEntity$(Plan,com.optrak.bi.etl.Projects$Plan) and primary keys List(2)
key not found: EntityType(PlanVersion)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$selectInner$1.apply(MapperDaoImpl.scala:179)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$selectInner$1.apply(MapperDaoImpl.scala:179)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:46)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:45)
at com.googlecode.mapperdao.internal.EntityMap.get(EntityMap.scala:45)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.selectInner(MapperDaoImpl.scala:178)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.select0(MapperDaoImpl.scala:163)
at com.googlecode.mapperdao.MapperDao$class.select(MapperDao.scala:245)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.select(MapperDaoImpl.scala:29)
at com.googlecode.mapperdao.MapperDao$class.select(MapperDao.scala:230)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.select(MapperDaoImpl.scala:29)
at com.optrak.bi.etl.TestDataConnections$$anonfun$1$$anonfun$apply$3.apply(TestDataConnections.scala:102)
at com.optrak.bi.etl.TestDataConnections$$anonfun$1$$anonfun$apply$3.apply(TestDataConnections.scala:101)
Caused by: java.util.NoSuchElementException: key not found: EntityType(PlanVersion)
at com.googlecode.mapperdao.TypeRegistry.persistDetails(TypeRegistry.scala:46)
at com.googlecode.mapperdao.state.recreation.MockFactory.createMock(MockFactory.scala:31)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1$$anonfun$apply$1.apply(MapperDaoImpl.scala:253)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1$$anonfun$apply$1.apply(MapperDaoImpl.scala:251)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:46)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:45)
at com.googlecode.mapperdao.internal.EntityMap.get(EntityMap.scala:45)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1.apply(MapperDaoImpl.scala:251)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1.apply(MapperDaoImpl.scala:234)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.toEntities(MapperDaoImpl.scala:233)
at com.googlecode.mapperdao.plugins.OneToManyEntityLazyLoader.apply(OneToManyEntityLazyLoader.scala:37)
at com.googlecode.mapperdao.plugins.OneToManyEntityLazyLoader.apply(OneToManyEntityLazyLoader.scala:14)
at com.googlecode.mapperdao.ValuesMap.valueOf(ValuesMap.scala:79)
at com.googlecode.mapperdao.ValuesMap.valueOf(ValuesMap.scala:56)
at com.googlecode.mapperdao.ValuesMap.apply(ValuesMap.scala:118)
at com.googlecode.mapperdao.Entity.columnTraversableOneToManySet(Entity.scala:247)
at com.optrak.bi.etl.BIPersist$PlanEntity$$anon$2.<init>(BIPersist.scala:160)
at com.optrak.bi.etl.BIPersist$PlanEntity$.constructor(BIPersist.scala:160)
at com.optrak.bi.etl.BIPersist$PlanEntity$.constructor(BIPersist.scala:155)
at com.googlecode.mapperdao.Entity.constructor(Entity.scala:83)
at com.googlecode.mapperdao.Entity$$anonfun$2.apply(Entity.scala:94)
at com.googlecode.mapperdao.Entity$$anonfun$2.apply(Entity.scala:92)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1$$anonfun$apply$1.apply(MapperDaoImpl.scala:268)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1$$anonfun$apply$1.apply(MapperDaoImpl.scala:251)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:46)
at com.googlecode.mapperdao.internal.EntityMap$$anonfun$get$1.apply(EntityMap.scala:45)
at com.googlecode.mapperdao.internal.EntityMap.get(EntityMap.scala:45)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1.apply(MapperDaoImpl.scala:251)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$toEntities$1.apply(MapperDaoImpl.scala:234)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl.toEntities(MapperDaoImpl.scala:233)
at com.googlecode.mapperdao.jdbc.impl.MapperDaoImpl$$anonfun$selectInner$1.apply(MapperDaoImpl.scala:218)
... 12 more

But the query runs correctly and returns the obvious result when I run it in the interactive shell. There is a record with a plan_id of 2. 

FYI the entire thing is read-only and I don't want to have a many-to-many-reverse in this context.

I don't mind trying to boil it down into a much smaller test case but I thought I'd just check if there's anything obviously wrong before doing so. 

My entities looks like this

object PlanVersionEntity extends Entity[Int, NaturalIntId, PlanVersion]("plan_version")  {
    override val databaseSchema = DefaultPersist.dwSchema
    val id = key("id") to (_.id)
    val scheduleItems = manytomany(ScheduleItemEntity) to (_.scheduleItems)
    def constructor(implicit m: ValuesMap) = new PlanVersion(id, scheduleItems) with Stored
  }

    object ScheduleItemEntity extends Entity[Int, NaturalIntId, ScheduleItem]("schedule_item") with NaturalIntId {
      override val databaseSchema = DefaultPersist.dwSchema
      val id = key("id") to (_.id)
      val shiftId = column("shift_id") option (_.shiftId) // not all schedule items are linked option a driver shift - daily rest is not
//      val trip = manytoone(TripEntity) foreignkey("trip_id") option (_.trip) // note this can be null as not all schedule items are linked directly to a trip (e.g. break/ admin)
      val tripPosition = column("trip_position") option (_.tripPosition)
      val isFixed = column("is_Fixed") to (_.isFixed)
//      val driver = manytoone(DriverEntity) foreignkey("driver_id") to (_.driver)
      val driverPosition = column("driver_position") to (_.driverPosition)
      val start = column("start") to (_.start)
      val finish = column("finish") to (_.finish)
      val activity = column("activity_type_id") to (_.activityTypeId)
      val realtimeStatus = column("realtime_status_id") to (_.realtimeStatusId)
      val duration = column("duration") to (_.duration)
      val startLocation = manytoone(SiteEntity) foreignkey("start_location") option (_.startLocation)
      val finishLocation = manytoone(SiteEntity) foreignkey ("finish_location") option (_.finishLocation)
      val kms = column("kms") option (_.kms)
      val kmsTo = column("kms_To") option (_.kmsTo)
      val isEmptyDriving = column("is_empty_driving") option (_.isEmptyDriving)
      val cost = column("cost") option (_.cost)
      val startTime = column("start_time") to (_.startTime)
      val startDate = column("start_date") to (_.startDate)
      val finishTime = column("finish_time") to (_.finishTime)
      val finishDate = column("finish_date") to (_.finishDate)
//      val visit = manytoone(VisitEntity) foreignkey("visit_id") option (_.visit)

      def constructor(implicit m: ValuesMap) = new ScheduleItem(
        id,
        shiftId,
        None, //trip,
        tripPosition,
        isFixed,
//        driver,
        driverPosition,
        start,
        finish,
        activity,
        realtimeStatus,
        duration,
        startLocation,
        finishLocation,
        kms,
        kmsTo,
        isEmptyDriving,
        cost,
        startTime,
        startDate,
        finishTime,
        finishDate,
      None
//      visit
      ) with Stored
    }

objects: 
  case class PlanVersion(
    id: Int,
    scheduleItems: Set[ScheduleItem]
  )

  class ScheduleItem (
     val id: Int,
     val shiftId: Option[Int], // not all schedule items are linked to a driver shift - daily rest is not
     val trip: Option[Trip], // note this can be null as not all schedule items are linked directly to a trip (e.g. break/ admin)
     val tripPosition: Option[Int] ,
     val isFixed: Boolean,
//     val driver: Driver,
     val driverPosition: Int,
     val start: DateTime,
     val finish: DateTime,
     val activityTypeId: Int,
     val realtimeStatusId: Int,
     val duration: Int,
     val startLocation: Option[Site],
     val finishLocation: Option[Site],
     val kms: Option[Double],
     val kmsTo: Option[Double],
     val isEmptyDriving: Option[Boolean],
     val cost: Option[Double],
     val startTime: Int,
     val startDate: Int,
     val finishTime: Int,
     val finishDate: Int,
    //  val visit: Visit
         val visit: Option[Visit]
  )

and tables:

create table dw.plan_version (
  id int default nextval('dw.plan_version_id_seq'::regclass) primary key not null,
  plan_id int not null,
  constraint fk_version_plan foreign key (plan_id) references dw.plan(id) on delete cascade
);
create index is_version_plan on dw.plan_version(plan_id);

/*
schedule_item is part of solution and specific to plan
*/
CREATE TABLE dw.schedule_item (
id serial primary key,
plan_id int not null,
shift_id int, -- not all schedule items are linked to a driver shift - daily rest is not
trip_id int, -- note this can be null as not all schedule items are linked directly to a trip (e.g. break/ admin)
trip_position int4 ,
is_fixed bool not null,
driver_id int not null,
driver_position int4 not null,
start timestamptz not null,
finish timestamptz not null,
activity_type_id  int not null,
realtime_status_id int not null,
duration int not null,
start_location int,
finish_location int,
kms float8 ,
kms_to float8,
is_empty_driving bool ,
cost float8,
start_time int not null,
start_date int not null,
finish_time int not null,
finish_date int not null,
visit_id int,
constraint fk_schedule_item_plan foreign key(plan_id) references dw.plan on delete cascade,
constraint fk_schedule_item_shift foreign key(shift_id) references dw.shift(id) on delete cascade,
constraint fk_schedule_item_start_location foreign key(start_location) references dw.site(id) on delete cascade,
constraint fk_schedule_item_finish_location foreign key(finish_location) references dw.site(id) on delete cascade,
constraint fk_schedule_item_driver foreign key(driver_id) references dw.driver(id) on delete cascade,
constraint fk_start_time foreign key (start_time) references mart.time_dimension,
constraint fk_finish_time foreign key (finish_time) references mart.time_dimension,
constraint fk_start_date foreign key (start_date) references mart.master_date,
constraint fk_finish_date foreign key (finish_date) references mart.master_date,
constraint fk_schedule_item_trip foreign key(trip_id) references dw.trip,
constraint fk_schedule_item_realtimestatus foreign key(realtime_status_id) references mart.realtime_status,
constraint fk_schedule_item_visit foreign key(visit_id) references dw.visit(id)
)
WITH (OIDS=FALSE);

create table dw.plan_version_schedule_item (
  plan_version_id int4 not null,
  schedule_item_id int4 not null,
  constraint pk_plan_version_schedule_item primary key (plan_version_id, schedule_item_id),
  constraint fk_plan_version_schedule_item_schedule_item foreign key(schedule_item_id) references dw.schedule_item(id) on delete cascade,
  constraint fk_plan_version_schedule_item_version foreign key(plan_version_id) references dw.plan_version(id) on delete cascade
);



Konstantinos Kougios

unread,
Aug 19, 2013, 12:10:08 PM8/19/13
to mapp...@googlegroups.com
ah, probably you need to register PlanVersion entity when configuring mapperdao
--
You received this message because you are subscribed to the Google Groups "mapperdao" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapperdao+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Tim Pigden

unread,
Aug 19, 2013, 12:24:27 PM8/19/13
to mapp...@googlegroups.com
ah - great, that fixes it. Thanks.
 But that's the second time that has caught me out with a seemingly spurious error message. Any chance you could trap it earlier?


--
Tim Pigden
Optrak Distribution Software Limited
+44 (0)1992 517100
http://www.linkedin.com/in/timpigden
http://optrak.com
Optrak Distribution Software Ltd is a limited company registered in England and Wales.
Company Registration No. 2327613 Registered Offices: Suite 6, Hoe Lane, Ware, SG12 9LR England 
This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Optrak Distribution Software Ltd. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error.

Konstantinos Kougios

unread,
Aug 19, 2013, 12:35:16 PM8/19/13
to mapp...@googlegroups.com
I'll add a better error message ("please register ...")
Reply all
Reply to author
Forward
0 new messages