2011-05-19 14 views
9

में बनाया मैं अपने MySQL डेटाबेस, इस तरह बनाया गया था, जिसमें दो तालिकाओं है:JDBC: पी पर विदेशी कुंजी एक ही लेन-देन

CREATE TABLE table1 (
    id int auto_increment, 
    name varchar(10), 
    primary key(id) 
) engine=innodb 

और

CREATE TABLE table2 (
    id_fk int, 
    stuff varchar(30), 
    CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE 
) engine=innodb 

(ये मूल टेबल नहीं हैं बिंदु यह है कि तालिका 2 में तालिका में प्राथमिक कुंजी का संदर्भ देने वाली एक विदेशी कुंजी है 1)

अब मेरे कोड में, मैं एक लेनदेन के भीतर दोनों तालिकाओं में प्रविष्टियां जोड़ना चाहता हूं। इसलिए मैं गलत पर autoCommit सेट:

MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails 

ऐसा लगता है कि प्राथमिक कुंजी लेन-देन में उपलब्ध नहीं है इससे पहले कि मैं प्रतिबद्ध:

Connection c = null;   

    PreparedStatement insertTable1 = null; 
    PreparedStatement insertTable2 = null; 

    try { 
     // dataSource was retreived via JNDI 
     c = dataSource.getConnection(); 
     c.setAutoCommit(false); 

     // will return the created primary key 
     insertTable1 = c.prepareStatement("INSERT INTO table1(name) VALUES(?)",Statement.RETURN_GENERATED_KEYS); 
     insertTable2 = c.prepareStatement("INSERT INTO table2 VALUES(?,?)"); 

     insertTable1.setString(1,"hage"); 
     int hageId = insertTable1.executeUpdate(); 

     insertTable2.setInt(1,hageId); 
     insertTable2.setString(2,"bla bla bla"); 
     insertTable2.executeUpdate(); 

     // commit 
     c.commit(); 
    } catch(SQLException e) { 
     c.rollback(); 
    } finally { 
     // close stuff 
    } 

जब मैं कोड ऊपर निष्पादित, मैं एक अपवाद मिलता है।

क्या मुझे यहां कुछ याद आ रही है? मुझे सच में लगता है कि जेनरेट की गई प्राथमिक कुंजी लेनदेन में उपलब्ध होनी चाहिए।

कार्यक्रम mysql-कनेक्टर 5.1.14 और MySQL 5.5.8

किसी भी मदद वास्तव में सराहना की का उपयोग कर एक Glassfish 3.0.1 पर चलता है!

सादर, हेग

उत्तर

5

आप लौटे अद्यतन आईडी के लिए कुछ छूट गया हो, तो आप इस तरह क्या करना है:

Long hageId = null; 

try { 
    result = insertTable1.executeUpdate(); 
} catch (Throwable e) { 
    ... 
} 

ResultSet rs = null; 

try { 
    rs = insertTable1.getGeneratedKeys(); 
    if (rs.next()) { 
     hageId = rs.getLong(1); 
    } 
... 
+0

धन्यवाद! यह अब पूरी तरह से काम करता है। लेकिन कुछ अभी भी अस्पष्ट नहीं है: कोड चलाने से पहले मेरी टेबल खाली थीं। इसलिए 'exececuteUpdate' ने प्रभावित पंक्तियों की संख्या लौटा दी (इस मामले में 1) जो जेनरेट आईडी भी है। मुझे लगता है कि यह भी काम करना चाहिए था - यह भी दूसरे रन में अपवाद उठाया होगा ... या 'generatedKeys() 'कुंजी उपलब्ध कराती है? – hage

+0

डाली गई पंक्ति आईडी पंक्ति + 1 तक शुरू होती है, जब तक कि आप अपनी तालिका पर 'ट्रंकेट' नहीं करते हैं, यह 0 – EricParis16

+0

+1 तक शुरू नहीं होगा। मैं इस उत्तर को लंबे समय पर देख रहा हूं –

1
इसके बजाय executeUpdate का उपयोग करने का

() निष्पादित() और फिर प्राथमिक कुंजी लौटने का उपयोग करें।

http://www.coderanch.com/t/301594/JDBC/java/Difference-between-execute-executeQuery-executeUpdate

लेकिन मैं db के साथ काम नहीं है ... तो मैं क्या कर सकता है एक गलती

+0

मुझे विभिन्न निष्पादन *() विधियों के बीच अंतर पता है। मैं बस गलत तरीके से कुंजी प्राप्त करने की कोशिश कर रहा था। मैंने सोचा कि executeUpdate() 'Statement.RETURN_GENERATED_KEYS' सेट होने पर बदली गई पंक्तियों की संख्या के बजाय कुंजी वापस कर देगा। लेकिन वैसे भी आपके जवाब के लिए धन्यवाद। – hage

संबंधित मुद्दे