2016-03-08 37 views
0

我有一個使用JPA和H2來存儲數據的Spring服務器。如何編輯列值避免外鍵錯誤

數據庫表使用這個類創建:

@Entity 
public class parametros { 


    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id; 

    long idproject; 

    @ElementCollection(fetch=FetchType.EAGER) 
    List<String> answers = new ArrayList<String>(); 

    public parametros(){ 
    } 
    .../* gets and sets */ 
} 

所以,JPA和H2自動創建和Table="parametros"內的數據庫中的另一個Table="parametros_answers"這樣的:

Table = "parametros" 
ID | IDPROJECT 
1 |  3 
2 |  6  


Table="parametros_answers" 
PARAMETROS_ID | ANSWERS 
1    | Masculine 
1    | Female 
1    | Other 
2    | Cocacola 
2    | Pepsi 

因此,該系統是在Table = "parametros_answer"中創建一個外鍵。

直到這一點都可以。當我嘗試編輯Table = "parametros"的列值時,問題就出現了。我知道更改列值的唯一方法是使用UPDATE SET語句。所以,當我嘗試做:

UPDATE PARAMETROS SET IDPROJECT=10 WHERE IDPROJECT=3這個錯誤出現:

Error "DELETE FROM PUBLIC.PARAMETROS WHERE ID=? AND IDPROJECT=? , cause: "org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: ""FK_NFSJ58KBBAYJ84HFJLOCV9JEQ: PUBLIC.PARAMETROS_ANSWERS FOREIGN KEY(PARAMETROS_ID) REFERENCES PUBLIC.PARAMETROS(ID) (1)""; SQL statement: DELETE FROM PUBLIC.PARAMETROS WHERE ID=? AND EXTRA_CONF=? AND IDPROJECT=? AND MULTI_MAXIMUM=? AND MULTI_MINIMUM=? AND NOTE=? AND PERGUNTA=? AND TITLE=? AND TYPE=? [23503-187]"; SQL statement:

+0

你確定你正在更新嗎?似乎你正在刪除一些記錄 –

+0

是的,這對我來說也很奇怪。我只是在H2控制檯中執行'UPDATE PARAMETROS SET IDPROJECT = 10 WHERE IDPROJECT = 3' –

+0

你使用的是什麼版本的h2? –

回答

-1

所以,我不知道,如果這個解決方案是最好的但是唯一一個適合我的人。當DataBase爲空時,@highstakes解決方案可能會工作,但在我的情況下不是。 步驟i如下:

1 - 複製parametros_answers表(其具有foreig密鑰的那一個)是這樣的:

CREATE TABLE PARAMETROS_ANSWERS_AUX AS SELECT * FROM PARAMETROS_ANSWERS

2 - 刪除parametros_answers表:

DROP TABLE PARAMETROS_ANSWER

2 - 之後,我可以在parametros表上做我需要的更改:

UPDATE PARAMETROS SET IDPROJECT=10 WHERE IDPROJECT=3

3 - 我通過複製再parametros_answers創建從parametros_answers_aux表:

CREATE TABLE PARAMETROS_ANSWERS AS SELECT * FROM PARAMETROS_ANSWERS_AUX

4 - 最後,我可以刪除附配表parametros_answers_aux

DROP TABLE PARAMETROS_ANSWERS_AUX

+0

找到了一種強制違反外鍵的方法?這不是一個解決方案... – highstakes

1

例外說是什麼問題:你違反了參照完整性。

  • 所有'parametros_answers'行都必須指向'parametros'。如果不刪除或更新同一交易中的'parametros_answers'中的連接,則無法刪除或更新'parametros'。
  • 或刪除外鍵約束。如果相應標記集合
  • 或者使用EntityManager的自動刪除/更新這些行:@Cascade(值= {} CascadeType.ALL)
+0

我想嘗試你最後的建議,所以這'@Cascade(value = {CascadeType.ALL})'註釋我必須添加在我的列表上面 answers = new ArrayList ();'? –

+1

是的,但我不確定這將適用於JPQL,我知道它沒有刪除操作,但它可能適用於更新。你將不得不使用entitmanager.merge並刪除JPQL不起作用。 – highstakes

+0

另一種可能性依賴於數據庫:對數據庫模式使用級聯操作(如果可以更改數據庫模式)。該操作更原子,更快,更安全! – rlm