#java #jdbc #mariadb #rowset #cachedrowset
Вопрос:
Из того, что я прочитал в SyncResolver javadoc:
Приложение может вызвать метод SyncResolver getConflictValue для извлечения значения в источнике данных, которое является причиной конфликта, поскольку значения в объекте SyncResolver являются значениями конфликта из источника данных.
Поэтому я воспроизводю эту ситуацию, но по какой-то причине метод возвращает значение null, как будто конфликта вообще нет.
Определение таблицы:
MariaDB [testdb]> SHOW COLUMNS FROM COFFEES;
---------- --------------- ------ ----- --------- -------
| Field | Type | Null | Key | Default | Extra |
---------- --------------- ------ ----- --------- -------
| COF_NAME | varchar(32) | NO | PRI | NULL | |
| SUP_ID | int(11) | NO | MUL | NULL | |
| PRICE | decimal(10,2) | NO | | NULL | |
| SALES | int(11) | NO | | NULL | |
| TOTAL | int(11) | YES | | NULL | |
---------- --------------- ------ ----- --------- -------
Содержание таблицы:
MariaDB [testdb]> SELECT * FROM COFFEES;
-------------------- -------- ------- ------- -------
| COF_NAME | SUP_ID | PRICE | SALES | TOTAL |
-------------------- -------- ------- ------- -------
| Amaretto | 49 | 15.61 | 0 | 10 |
| Amaretto_decaf | 49 | 17.18 | 0 | 20 |
| Colombian | 101 | 15.61 | 175 | 525 |
| Colombian_Decaf | 101 | 17.56 | 155 | 465 |
| Espresso | 150 | 19.51 | 60 | 180 |
| French_Roast | 49 | 17.56 | 150 | 450 |
| French_Roast_Decaf | 49 | 19.51 | 90 | 270 |
| Hazelnut | 49 | 15.61 | 0 | 0 |
| Hazelnut_decaf | 49 | 17.18 | 0 | 0 |
| Kona | 150 | 17.18 | 0 | 0 |
-------------------- -------- ------- ------- -------
Код Java для его тестирования:
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetProvider;
import javax.sql.rowset.spi.SyncProviderException;
import javax.sql.rowset.spi.SyncResolver;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class MinimalExample {
private static final String USER_NAME = "ewa";
private static final String URL = "jdbc:mariadb://localhost:3306/testdb";
private static final int VALUE_TO_SET = 10;
private static final int COLUMN_INDEX = 5;
public static void main(String[] args) throws SQLException, IOException {
var rowSet = createRowSet();
rowSet.setCommand("SELECT * FROM COFFEES");
rowSet.execute();
updateRowSet(rowSet);
}
private static void updateRowSet(CachedRowSet rowSet) throws SQLException {
rowSet.beforeFirst();
rowSet.next();
rowSet.updateInt(COLUMN_INDEX, VALUE_TO_SET);
rowSet.updateRow();
try (var connection = prepareConnection()) {
rowSet.acceptChanges(connection);
} catch (SyncProviderException exception) {
System.out.println("Conflict detected.");
solveConflicts(exception.getSyncResolver());
}
}
private static void solveConflicts(SyncResolver resolver) throws SQLException {
while (resolver.nextConflict()) {
System.out.println("Conflict on " resolver.getRow() " row.");
System.out.println(resolver.getConflictValue(COLUMN_INDEX));
}
}
private static Connection prepareConnection() throws SQLException {
var properties = new Properties();
properties.put("user", USER_NAME);
var connection = DriverManager.getConnection(URL, properties);
connection.setAutoCommit(false);
return connection;
}
private static CachedRowSet createRowSet() throws SQLException {
var factory = RowSetProvider.newFactory();
var rowSet = factory.createCachedRowSet();
rowSet.setUsername(USER_NAME);
rowSet.setUrl(URL);
return rowSet;
}
}
Я устанавливаю точку останова в начале метода updateRowSet и запускаю следующую инструкцию извне программы (терминал):
UPDATE COFFEES SET TOTAL = 60 WHERE COF_NAME = 'Amaretto';
Я 60
каждый раз меняю номер, чтобы вызвать конфликт.
Я использую Java 11 и MariaDB 2.53.