not supported on forward only result sets in Java

0

I am trying to fill a JTable with the records that a table has in my database in SQL.

I receive this error:

  

com.microsoft.sqlserver.jdbc.SQLServerException: The requested   operation is not supported on forward only result sets.

Stack Trace:

com.microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.throwNotScrollable(SQLServerResultSet.java:414)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.verifyResultSetIsScrollable(SQLServerResultSet.java:437)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.last(SQLServerResultSet.java:1477)
    at logicas.Logica_usuarios.tableRegistros(Logica_usuarios.java:28)
    at vistas.Vista_usuarios.tableRegistros(Vista_usuarios.java:38)
    at vistas.Vista_usuarios.<init>(Vista_usuarios.java:117)
    at vistas.Vista_usuarios$1.run(Vista_usuarios.java:56)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

JTable Code:

JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(12, 73, 598, 187);
        contentPane.add(scrollPane);

        table = new JTable();
        scrollPane.setViewportView(table);

        tableRegistros();

Procedure tableRegistros ();

void tableRegistros() {
        try {
            Logica_usuarios l_users = new Logica_usuarios();
            DefaultTableModel model;
            model = l_users.tableRegistros();
            table.setModel(model);
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            table.getColumnModel().getColumn(0).setMinWidth(50);
            table.getColumnModel().getColumn(0).setMaxWidth(50);
            table.getColumnModel().getColumn(0).setPreferredWidth(50);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Exception:\n" + e, "Error: Vista_usuarios.tableRegistros()", JOptionPane.ERROR_MESSAGE);
            }
    }

Code of the connection in SQL and of the filling (public class Logica_usuarios):

public DefaultTableModel tableRegistros() {
        DefaultTableModel model = null;

        sSQL = "SELECT * FROM usuarios";

        // Java 7 try-with-resources
        try (Statement st = conn.createStatement();
             ResultSet rs = st.executeQuery(sSQL)) {

            String [] titulosColumnas = {"Nombre", "Apellido", "Usuario", "Contraseña"};

            rs.last();
            int filas = rs.getRow();
            rs.first();

            Object [][] registros = new Object[filas][titulosColumnas.length]; 

            int i = 0;
            do {
                registros[i][1] = rs.getString("nombre");
                registros[i][2] = rs.getString("apellido");
                registros[i][3] = rs.getString("usuario");
                registros[i][4] = rs.getString("contrasena");
                i++;
            } while (rs.next());

            model = new DefaultTableModel(registros, titulosColumnas);

        } catch (SQLException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "SQLException:\n" + e, "Error: Logica_usuarios.tableRegistros()", JOptionPane.ERROR_MESSAGE);
            }

        return model;
    }

I can not find the solution, I hope you can help me discover what I did wrong. Thanks in advance.

    
asked by Robert Gomez 07.11.2017 в 19:06
source

1 answer

1

According to the stack trace, the error comes from this statement:

rs.last();

By default, the result sets are forward only , that is, you can only read one record at a time and forward nothing else. Calls like last() or first() will not work.

If you used a PreparedStatement you could change the type of result set you get to enable these methods, but I do not think it's worth doing this in your case.

In your case, the only reason you are making this call is because you are trying to determine the number of records in advance.

I suggest you change the logic so that you do not need this information beforehand. You can do this by changing the array to ArrayList and converting it to an array at the end.

By the way, even if you did not have that problem, you were going to face others later. The code is full of errors. For example, you are using do-while which is incorrect because you try to read the first record before calling rs.next() . Also, your use of registros within the loop would cause a NullPointerException . You are also assuming that the first index of the arrays is 1 , this is incorrect.

Here I leave an extract of code that corrects these problems:

String [] titulosColumnas = {"Nombre", "Apellido", "Usuario", "Contraseña"};
ArrayList<Object[]> registros = new ArrayList<Object[]>();

while (rs.next()) {
    registros.add(new Object[] {
        rs.getString("nombre"),
        rs.getString("apellido"),
        rs.getString("usuario"),
        rs.getString("contrasena")
    });
}

model = new DefaultTableModel(registros.toArray(new Object[0][]), titulosColumnas);
    
answered by 08.11.2017 / 00:01
source