2013-10-08 116 views
0

在我的應用程序中,當User刪除Message時,我需要刪除2個實體之間的關係,同時保持它們完好無損。因此,我試圖從關係表,可以使用以下方式直接刪除行:原生查詢產生MySQL語法錯誤和意外結果

1.

Query q = em.createNativeQuery("DELETE FROM User_Inbox WHERE User_USERNAME = :username AND Message_ID = :messageID"); 
q.setParameter("username", username); 
q.setParameter("messageID", messageID); 
q.executeUpdate(); 

2.

Query q = em.createNativeQuery("DELETE FROM User_Inbox WHERE User_USERNAME = :username AND Message_ID = :messageID"); 
q.setParameter("username", "'" + username + "'"); 
q.setParameter("messageID", "'" + messageID + "'"); 
q.executeUpdate(); 

的第一和第二方法產生的以下例外:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 
You have an error in your SQL syntax; check the manual that corresponds to your 
MySQL server version for the right syntax to use near ':username AND 
Message_ID = :messageID' at line 1 
Error Code: 1064 

Query q = em.createNativeQuery("DELETE FROM User_Inbox WHERE User_USERNAME = ':username' AND Message_ID = ':messageID'"); 
q.setParameter("username", username); 
q.setParameter("messageID", messageID); 
q.executeUpdate(); 

第三屆做法並沒有產生任何異常。它正常通過。但是,User_Inbox表中沒有任何內容被刪除。

4.

Query q = em.createNativeQuery("DELETE FROM User_Inbox WHERE User_USERNAME = '" + username + "' AND Message_ID = '" + messageID + "'"); 
q.executeUpdate(); 

第四屆方法完美。查詢順利進行,記錄被正確刪除。

最後一種方法奏效,但代碼看起來並不整齊。如果有人能告訴我我在前三種方法中做錯了什麼,我將非常感激。

UPDATE:

基礎上answer從D·穆爾,我剛剛發現,命名參數不能與本機查詢使用。這在Pascal Thivent的answer中已經提到。

命名參數遵循 中定義的標識符的規則4.4.1。命名參數的使用適用於Java持久性查詢語言,並且未針對本機查詢定義。 只有 位置參數綁定可以可移植地用於本機 查詢。

+0

查詢使用模式中的表和列,它是如何映射到java對象的? – 2013-10-08 17:05:52

+0

@nikpon:有兩個實體叫'User'和'Message',它們之間有'@ ManyToMany'關係。但是,我並沒有從這兩個實體的表格中刪除任何東西。我需要從'@ ManyToMany'關係創建的'@ JoinTable'中刪除記錄。 –

+0

實體刪除您可以發現一個連接表的簡單情況,只包含您使用本機查詢而不是從實體管理器中刪除的引用。 – 2013-10-08 17:22:13

回答

1

我同意(4.)當然不是正確的做事方式。這是乏味和不安全的。

(3.)正在工作,但由於它們有額外的引號而沒有產生預期的結果。至於爲什麼(1.)不起作用,你會想看看正在生成的SQL(我相信這些設置是特定於你正在使用的JPA系統的)。你似乎有正確的代碼,但錯誤意味着參數不被替換。

位置參數是否有不同的作用?

Query q = em.createNativeQuery("DELETE FROM User_Inbox WHERE User_USERNAME = ?1 AND Message_ID = ?2"); 
q.setParameter(1, username); 
q.setParameter(2, messageID); 
q.executeUpdate(); 
+0

這是使用什麼樣的參數?爲什麼不在JPA中使用命名參數? – 2013-10-08 17:25:17