2011-11-15 106 views
1

我試圖用Squeryl從一個數據庫中取出一個表的內容,並將它附加到另一個數據庫的等效表中。主鍵將不得不在該過程中重新分配,但我得到NULL「不允許列」SIMID「的錯誤。爲什麼是這樣?用Squeryl連接數據庫

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的URL和文件都在這裏:resultsA.trace.dbresultsB.trace.db。 B是我認爲更有趣的一個。另外,我已經放入了數據庫here的簡化版本,該版本刪除了不必要的表(相同的數據庫用於resultsA和resultsB)。

+0

你使用什麼版本的Squeryl?你會願意發佈一個可重複的測試用例給github,這樣我可以看看嗎? –

+0

我幾天沒有工作,所以不能立即發佈空白測試數據庫,但添加了一個更新,我希望能夠提供一些線索。謝謝 – Pengin

+0

您能否將'; trace_level_file = 3'附加到數據庫URL,然後檢查或上傳'.trace.db'文件?它應該包含導致該問題的所有JDBC方法調用。 –

回答

1

只是有一點時間仔細看看這個。我發現你是在正確的軌道上。雖然我猜的EclipseLink使用序列來產生PK值,Squeryl列定義爲這樣的:

SIMID BIGINT NOT NULL主鍵AUTO_INCREMENT

沒有AUTO_INCREMENT標誌的值永遠不會放置在列你最終會遇到你提到的約束違規。這聽起來像你已經解決了這個問題,但希望這將有助於你或其他人在未來。

+0

感謝您的確認 – Pengin

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獲得適當覆蓋。