我使用了this question中的解决方案。
我使用了公认的答案:
方法
def insertRequiredDocIfNotExists(keys: DocumentInfo) = {
val documentMasterId = "hardcoded_value 1"
val documentMasterCategory = "hardcoded value 2"
val action = {
RequiredDocuments.filter(_.required_document_id__k === keys.documentId)
.result
.headOption
.flatMap{
case Some(doc) =>
logger.debug("Required doc already exists")
DBIO.successful(doc)
case None =>
RequiredDocuments.map(rd => (
rd.doc_master_list__k,
rd.doc_category__k,
rd.applicant_id__k,
rd.application_id__k,
rd.name,
rd.required_document_id__k,
rd.type_k
)) += (
Some("Job Application 1"),
Some("Resume"),
Some("Job Applicant 1"),
Some("Lead for Applicant 1"),
Some("Resume ID 224"),
Some("Last 6 months WorkExperience Resume"),
Some("General")
)
}
}.transactionally
val db = Connections.getSaleForceSchemaDBObject().db
db.run(action)
}
用法
Await.result(insertRequiredDocIfNotExists(keys), Duration.Inf)
// inserts into other tables.
日志
错误消息如下:
ERROR: duplicate key value violates unique constraint "hcu_idx_required_document__c_required_document_uuid__c"
Detail: Key (required_document_id__k)=(c63386c0-d599-4d47-a535-941a24a07a6e) already exists.: org.postgresql.util.PSQLException
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "required_document_id__k"
Detail: Key (required_document_uuid__c)=(c63386c0-d599-4d47-a535-941a24a07a6e) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2433)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2178)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:306)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:132)
at slick.jdbc.LoggingPreparedStatement.$anonfun$executeUpdate$5(LoggingStatement.scala:155)
at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.java:12)
at slick.jdbc.LoggingStatement.logged(LoggingStatement.scala:84)
at slick.jdbc.LoggingPreparedStatement.executeUpdate(LoggingStatement.scala:155)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl$SingleInsertAction.$anonfun$run$11(JdbcActionComponent.scala:510)
at slick.jdbc.JdbcBackend$SessionDef.withPreparedStatement(JdbcBackend.scala:386)
at slick.jdbc.JdbcBackend$SessionDef.withPreparedStatement$(JdbcBackend.scala:381)
at slick.jdbc.JdbcBackend$BaseSession.withPreparedStatement(JdbcBackend.scala:448)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl.preparedInsert(JdbcActionComponent.scala:501)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl$SingleInsertAction.run(JdbcActionComponent.scala:507)
at slick.jdbc.JdbcActionComponent$SimpleJdbcProfileAction.run(JdbcActionComponent.scala:30)
at slick.jdbc.JdbcActionComponent$SimpleJdbcProfileAction.run(JdbcActionComponent.scala:27)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.liftedTree1$1(BasicBackend.scala:275)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.run(BasicBackend.scala:275)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Slick具有一个upsert
方法,该方法可以更新一个项目(如果存在)。我不想使用upsert
,因为每个周期最多将同一项目最多更新20次是没有意义的。
答案 0 :(得分:1)
对于这个问题,可能的解决方案是进行一个事务,该事务的两端都要查询要检查的存在值,然后进行可能的插入...考虑到DBIOAction是monad,则可以编写一些解决方案喜欢:
val query = RequiredDocuments.filter(_.required_document_id__k === keys.documentId)
val newRecord = {
(
Some("Job Application 1"),
Some("Resume"),
Some("Job Applicant 1"),
Some("Lead for Applicant 1"),
Some("Resume ID 224"),
Some("Last 6 months WorkExperience Resume"),
Some("General")
)
}
val finalQuery = {
query.exists.result.flatMap{ exitingRecord =>
if (!exitingRecord) {
RequiredDocuments.map{rd => (
rd.doc_master_list__k,
rd.doc_category__k,
rd.applicant_id__k,
rd.application_id__k,
rd.name,
rd.required_document_id__k,
rd.type_k
)} += newRecord
} else {
DBIO.successful(None)
}
}
}
db.run(finalQuery.transactionally)
希望有帮助:)