Coming from How to get max(id) of table = Rep[Option[Long]] for subsequent insert, without calling db.run in between
I have yet another problem with my code:
def add(languageCode: String,
typeId: Long,
properties: Seq[Property]): Unit = {
val dbAction = (
for{
nodeId <- (nodes.all returning nodes.all.map(_.id)) += Node(typeId)
language <- (languages.all filter (_.code === languageCode)).result.head
_ <- DBIO.seq(properties.map
{
property =>
val id = property.id
val name = property.key
val value = property.value
if(id == 0) {
val currentPropId: FixedSqlAction[Option[Long], h2Profile.api.NoStream, Effect.Read] = this.properties.all.map(_.id).max.result
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, currentPropId + 1, name)
nodeProperties.all += NodeProperty(nodeId, 2, value)
} else {
nodeProperties.all += NodeProperty(nodeId, id, value)
}
}: _*)
} yield()).transactionally
db.run(dbAction)
}
1) The basic idea is, that if that for each property which has id of 0, there are two inserts to be called. One to actually create that new property in some table, the other to also add the value of that property to another table.
That's in the:
if(id == 0) {
val currentPropId: Rep[Option[Long]] = this.properties.all.map(_.id).max
// FIXME get rid of hardcoded languageId
val DUMMY_LANGUAGE_ID = 1
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(DUMMY_LANGUAGE_ID, currentPropId + 1, name)
nodeProperties.all += NodeProperty(nodeId, 2, value)
}
part.
Now, if that is not the case, only the value of the property needs to be inserted to the correct table, that's what the else
part is for.
The problem I face is that for the case where the id == 0
nothing gets inserted.
I also tried it like this:
if(id == 0) {
val nextPropId: Rep[Option[Long]] = this.properties.all.map(_.id).max
// FIXME get rid of hardcoded languageId
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(1, 10, name)
val nodeProperty = nodeProperties.all += NodeProperty(nodeId, 2, value)
propertyId andThen nodeProperty
}
but to no avail.
The else
part works just fine. What am I missing here?
edit:
Because I got asked.
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, 10, name)
val nodeProperty = nodeProperties.all += NodeProperty(nodeId, 2, value)
log.info(s"Statements: ${propertyId.statements}")
log.info(s"${nodeProperty.statements}")
gives me:
Statements: Vector(insert into "properties" ("language_id","property_id","name") values (?,?,?)) Vector(insert into "node_property" ("node_id","property_id","value") values (?,?,?))
Which looks just fine.
I would love to log also the content of dbAction
itself but as it's a DBIOAction
I did not find a way to do so in a meaningful manner.
If I set my logging to trace I get:
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - ------------------- Phase: Time ---------
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - assignUniqueSymbols: 0.456428 ms
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - inferTypes: 0.089135 ms
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - insertCompiler: 0.292443 ms
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - codeGen: 0.534494 ms
22:18:16:016 - [debug] s.c.QueryCompilerBenchmark - TOTAL: 1.372500 ms
22:18:16:016 - [debug] s.b.B.action - #5: Rollback
With no idea why the last line says Rollback
as everything before (quite a lot more) seems okay to me.
edit2:
Looks like I finally have it with:
val dbAction = for {
nodeId <- (nodes.all returning nodes.all.map(_.id)) += Node(typeId)
languageId <- (languages.all filter (_.code === languageCode)).map(_.id).result.head
_ <- DBIO.seq(properties.values.map
{
property =>
val id = property.id
val name = property.key
val value = property.value
if(id == 0) {
for {
currentPropId <- this.properties.all.map(_.id).max.result
propertyId <- (this.properties.all returning this.properties.all.map(_.id)) += Property(languageId, currentPropId.get + 1, name)
_ <- this.nodeProperties.all += NodeProperty(nodeId, propertyId, value)
} yield ()
} else {
this.nodeProperties.all += NodeProperty(nodeId, id, value)
}
}: _*)
} yield ()