我正在尝试使用Squeryl从一个数据库中获取表的内容,并将其附加到另一个数据库中的等效表中。主键必须在此过程中重新分配,但我收到错误 NULL不允许列“SIMID”。这是为什么?
object Concatenator {
def main(args: Array[String]) {
Class.forName("org.h2.Driver");
val seshA = Session.create(
java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsA", "sa", "password"),
new H2Adapter
)
val seshB = Session.create(
java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsB", "sa", "password"),
new H2Adapter
)
using(seshA){
import Library._
from(sims){s => select(s)}.foreach{item =>
using(seshB){
sims.insert(item);
}
}
}
}
case class Simulation(
@Column("SIMID")
var id: Long,
val date: Date
) extends KeyedEntity[Long]
object Library extends Schema {
val sims = table[Simulation]
on(sims)(s => declare(
s.id is(unique, indexed, autoIncremented)
))
}
}
更新 我认为这可能与数据库有关。它们是在使用JPA / EclipseLink的Java项目中创建的,除了为我的实体生成表之外,它还创建了一个名为SEQUENCE的表,可能用于生成主键。
我发现我可以在Squeryl中创建一个全新的表,并手动将两个数据库的内容放在其中,从而达到同样的效果。有趣的是,这个新表没有自动生成任何SEQUENCE表。所以我猜测它归结为JPA / EclipseLink如何生成我的主键?
更新2: 根据要求,我将trace_level_file = 3附加到网址,文件位于:resultsA.trace.db和resultsB.trace.db。 B是我认为更有趣的一个。另外,我放了一个简化版的数据库here,删除了不必要的表(同一个数据库用于resultsA和resultsB)。
答案 0 :(得分:1)
稍等一下,仔细看看这个。事实证明你是在正确的轨道上。虽然我猜EclipseLink使用Sequences来生成PK值,但Squeryl将列定义为:
simid bigint not null主键 auto_increment
如果没有auto_increment标志,则永远不会在列中放置一个值,最终会出现您提到的约束违规。听起来你已经解决了这个问题,但希望这将有助于你或其他人。
答案 1 :(得分:0)
不是真正的解决方案,但我的解决方法是创建一个新数据库
val seshNew = Session.create(java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsNew", "sa","password"),new H2Adapter)
然后只需将其他数据库中的所有数据写入其中
using(seshNew){
sims.insert(new Simulation(0,item.date))
}
主键0会被适当覆盖。