Immer "nicht Begehen, wenn autocommit aktiviert ist" Ausnahme während der Arbeit mit CachedRowSet in JDBC
Ich versuche zu implementieren eine einfache GUI-Anwendung für die Arbeit mit Datenbank-Datensätzen. Es enthält eine Ansicht der Datensätze und die Möglichkeit, Sie zu Bearbeiten. Hier ist, wie mein code sieht wie folgt aus:
class MainPanel extends JPanel {
private CachedRowSet crs;
private List<JTextField> fields = new LinkedList<>();
MainPanel() {
try {
//Fill result set with data
crs = new CachedRowSetImpl();
crs.setUrl("jdbc:postgresql:testdb");
crs.setUsername("username");
crs.setPassword("password");
crs.setCommand("SELECT * FROM products");
crs.execute();
//Create text fields with labels
ResultSetMetaData meta = crs.getMetaData();
for (int a = 1; a <= meta.getColumnCount(); a++) {
JTextField field = new JTextField(10);
add(new JLabel(meta.getColumnLabel(a)));
fields.add(field);
add(field);
}
//Fill fields on startup
crs.next();
updateFields();
//Buttons
JButton nextButton = new JButton("Next");
nextButton.addActionListener(...);
add(nextButton);
JButton prevButton = new JButton("Previous");
prevButton.addActionListener(...);
add(prevButton);
JButton saveButton = new JButton("Save changes");
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
try {
for (int a=0; a<fields.size(); a++) {
crs.updateString(a+1, fields.get(a).getText());
}
crs.acceptChanges();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
});
add(saveButton);
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
private void updateFields() throws SQLException {
for (int a = 0; a < fields.size(); a++) {
fields.get(a).setText(crs.getString(a + 1).trim());
}
}
}
Fuß zur nächsten und vorherigen arbeiten richtig. Aber ich bekomme eine Ausnahme beim speichern von Datensätzen. Der stack trace ist folgende:
org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled.
at org.postgresql.jdbc2.AbstractJdbc2Connection.commit(AbstractJdbc2Connection.java:705)
at com.sun.rowset.internal.CachedRowSetWriter.commit(CachedRowSetWriter.java:1396)
at com.sun.rowset.CachedRowSetImpl.acceptChanges(CachedRowSetImpl.java:893)
at test.MainPanel$3.actionPerformed(MainPanel.java:85)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
...
Wie kann ich verhindern, dass diese Ausnahme? Was ist auto-commit? Ich weiß, dass die Connection-Klasse hat eine option auf false gesetzt, aber ich don ' T wollen, verwenden Sie die Connection-Klasse. Ich möchte erreichen, alles mit CachedResultSet. Wie kann ich dieses problem beheben?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fügen Sie einfach
crs.getConnection ().setAutoCommit (false);
Fügen Sie die folgenden am Ende der URL:
Ich hatte das gleiche Problem-- CachedRowSetImpl.acceptChanges() nicht schalten Sie autocommit, und wenn geht es um die änderungen zu übernehmen, wird eine Ausnahme ausgelöst, da waren Sie schon begangen individuell.
Dies kann sein, weil PostgreSQL ist ein wenig wählerisch, autocommit. PostgreSQL erlaubt nicht ausschalten autocommit durch SQL-Anweisungen (obwohl es in seinen frühen Tagen). Stattdessen werden alle SQL-Anweisungen, müssen verpflichtet werden, die als Gruppe haben werden-eingeklemmt zwischen den SQL-Anweisungen BEGIN und COMMIT. PostgreSQL JDBC-Treiber unterstützt die Verbindung.setAutoCommit(false), aber ich Wette, es wird lediglich aufgefordert, den Treiber zu erstellen, der in einem BEGIN-COMMIT-sandwich hinter die kulissen. Meine Vermutung ist, dass CachedRowSetImpl.acceptChanges() ist, versucht die SQL-Anweisungen zum deaktivieren der autocommit-statt mit setAutoCommit(false) und das ist, warum es scheitern.
Die einzige Möglichkeit, die ich gefunden dieses problem zu umgehen, wurde, um eine temporäre Verbindung, schalten Sie autocommit aus, und übergeben Sie die Verbindung zu dem einen argument-version von acceptChanges. Anstatt also diese:
hätten Sie so etwas wie dieses:
Dies erfordert die Verwendung der Connection-Klasse, die Sie versuchen zu vermeiden, aber es kann nicht jeder alternative (kurze, nicht über JDBC). Sie nicht verwenden können, CachedRowSetImpl.getConnection (), denn das ruft nur dann eine Verbindung, die war extern erstellt und dann übergeben. Können Sie nicht angeben, durch die url, die Sie möchten autocommit auf off sein, da PostgreSQL nicht möglich. Es wäre toll, wenn CachedRowSetImpl.acceptChanges() konnte aktualisiert werden, so dass es erfolgreich deaktiviert autocommit auf seine eigenen. Dies scheint jedoch eher unwahrscheinlich, da mein compiler warnt, dass CachedRowSetImpl möglicherweise in einer zukünftigen Version entfernt.
Ich hatte ähnliche Probleme während der Arbeit mit CachedRowset. Ich bin mit dem MySQL Datenbank.
während Sie versucht, viele Lösungen. Endlich fand ich zwei Problemumgehungen, die für mich gearbeitet hat. Ich möchte Sie hier erwähnen:
Mithilfe des Connection-Objekts, und übergeben Sie an die
execute(con)
undacceptChanges(con)
Methoden. Auch setzensetAutoCommit(false)
.Beispiel:
Hinweis: Sie brauchen nicht, um die Eigenschaften von CachedRowset in diesem Fall wie
setURL()
,setUser()
undsetPassword()
. Weil das CachedRowset Objekt mit Connection-Objekt die Verbindung zur Datenbank wurde manuell erstellt und mitautocommit=false
Hinzufügen
?relaxAutoCommit=true
zu den URL wie erwähnt von bobby-paulose