Fetching row from Cassandra table with Spring - java

Hello am trying to fetch 10 rows of data from Cassandra table. But on each request same 10 row is returning. Please see my logic here. and advise me where am doing wrong here-
public class CustomerRequestDaoImpl implements CustomerRequestDao
{
private static Cluster cluster;
#Resource
private CassandraSessionFactory cassandraSessionFactory;
/** The ProductsByTagDaoImpl session. */
private Session session;
#Override
public List<CustomerRequest> getCustomerRequestData(final String productId, final String receiptPeriod)
{
final int RESULTS_PER_PAGE = 10;
session = cassandraSessionFactory.getSession();
final List<CustomerRequest> customerRequestdata = new ArrayList<CustomerRequest>();
try
{
final PreparedStatement statement =
session.prepare("select * from customer_request where product_id = :id and receipt_period = :receiptPeriod");
final BoundStatement boundStatement = new BoundStatement(statement);
boundStatement.setFetchSize(RESULTS_PER_PAGE);
boundStatement.setString("id", productId);
boundStatement.setString("receiptPeriod", receiptPeriod);
final ResultSet resultSet = session.execute(boundStatement);
final Iterator<Row> iter = resultSet.iterator();
final PagingState nextPage = resultSet.getExecutionInfo().getPagingState();
int remaining = resultSet.getAvailableWithoutFetching();
for (final Row rowdt : resultSet)
{
customerRequestdata.add(constructCustomerReq(rowdt));
if (--remaining == 0)
{
break;
}
}
}
catch (final Exception e)
{
e.printStackTrace();
}
return customerRequestdata;
}
#PostConstruct
public void init()
{
session = cassandraSessionFactory.getSession();
cluster = session.getCluster();
}
}
My Table-
My Table structure:-
CREATE TABLE customer_request (
product_id varchar PRIMARY KEY,
id varchar,
receipt_period varchar,
delivery_method_status varchar,
first_name varchar
);
return Response-
<e>
<deliveryMethodStatus null="true"/>
<firstName null="true"/>
<id>0b0352f6b3904</id>
<lastName Adkin="true"/>
<orderId>FORMS8a04e</orderId>
<orderItemId>FORMS8a04e-1</orderItemId>
<productId>PI_NAME_CHANGE</productId>
<receiptPeriod>2016-02-06</receiptPeriod>
<receivedDate null="true"/>
<requestData null="true"/>

Several remarks:
You should not re-prepare the query each time, it's an
anti-pattern. Prepare the statement only once and re-use it for each method call
The source code you show will always return the first page of
data because you break out of the for loop once remaining
variable counts down to 0. The PagingState object is not used
anywhere ...
You question is not clear either Hello am trying to fetch 10 rows of
data from Cassandra table. But on each request same 10 row is
returning. Which 10 rows do you want ? The first 10 rows ? The
10 rows after a threshold ?
Sample code for paging:
Note: prepared the following query only once: select * from customer_request where product_id = :id and receipt_period = :receiptPeriod LIMIT :lim and pass it along with the method
#Override
public List<Tuple2<String,CustomerRequest>> getCustomerRequestData(final String productId, PreparedStatement ps, final String receiptPeriod, String pagingState)
{
final int PAGE_SIZE = 10;
session = cassandraSessionFactory.getSession();
final List<CustomerRequest> customerRequestdata = new ArrayList<CustomerRequest>();
try
{
final BoundStatement boundStatement = ps.bind(productId, receiptPeriod, PAGE_SIZE);
boundStatement.setPagingState(PagingState.fromString(pagingState));
final ResultSet resultSet = session.execute(boundStatement);
final Iterator<Row> iter = resultSet.iterator();
final PagingState nextPage = resultSet.getExecutionInfo().getPagingState();
int remaining = resultSet.getAvailableWithoutFetching();
for (final Row rowdt : resultSet)
{
customerRequestdata.add(constructCustomerReq(rowdt));
if (--remaining == 0)
{
break;
}
}
}
catch (final Exception e)
{
e.printStackTrace();
}
return new Tuple2<>(nextPage.toString(), customerRe);
Please note the use of Tuple2 class to return the list of results as well as the paging state, serialized as a String to be passed easily to the front-end

Related

Is there a way to obtain the keys from a deleted record?

I'm using PostgreSQL to save a form in three tables, one for the name and id, another one for the fields to populate, and a third to store values for the fields.
private static final String REMOVE_FORM = "DELETE FROM forms WHERE name = ?";
private PreparedStatement removeFormQuery;
public boolean connect() throws SQLException{
this.connection = DriverManager.getConnection(URL);
this.removeFormQuery = this.connection.prepareStatement(REMOVE_FORM);
}
public void close() throws SQLException {
if(null != this.connection) {
this.connection.close();
}
if(null != this.removeFormQuery) {
this.removeFormQuery.close();
}
}
private void removeForm(String form) {
try {
removeFormQuery.setString(1, form);
int execute = removeFormQuery.executeUpdate();
System.out.println(execute);
ResultSet generatedKeys = removeFormQuery.getGeneratedKeys();
while (generatedKeys.next()) {
int anInt1 = generatedKeys.getInt("id");
removeFieldQuery.setInt(1, anInt1);
if (removeFieldQuery.execute())
System.out.println("remove field failed");
else
System.out.println("remove field success");
ResultSet generatedFieldsKeys = removeFieldQuery.getGeneratedKeys();
while (generatedFieldsKeys.next()) {
int anInt = generatedFieldsKeys.getInt("id");
removeListItemQuery.setInt(1, anInt);
if (removeListItemQuery.execute())
System.out.println("remove listItem failed");
else
System.out.println("remove listItem success");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
The code doesn't generate keys after the remove query is executed, am I missing something?
While you haven't told us what queries you are running, if they are deletes then you wouldn't expect any generated keys.
From the Javadoc for Statement.getGeneratedKeys():
* Retrieves any auto-generated keys created as a result of executing this
* Statement object. If this Statement object did
* not generate any keys, an empty ResultSet
* object is returned.
Keys may be auto generated when you insert into a table, creating a new row which needs a primary key, but when you delete a row no key generation occurs.

Check existing entry in database + auto increment id -> multiple conditions

I'm creating a GUI application with an user form to generate a sheet, those sheets are saved in the H2 database, as for the user form I enter manually the sheet number in a textfield and the date from a datepicker.
Every sheet has its ID which shall be unique for that month. The first created sheet for that month has id 1, and 2nd is 2 and so on but for the next month the ID should restart from 1.
I need to check if the entry already exists in the database with that sheet number in that month. I created another column in the database where the number+month+year I extract from the textfields are stored and I check it there, but I am looking for another method without having to create the extra column.
Here are the setter and getters (I pasted only the 3 values):
public class FiseDetails {
private final IntegerProperty sheetNumber;
private final ObjectProperty<Date> sheetDate;
private final StringProperty numberAndDate;
public FiseDetails(Integer sheetNumber, Date sheetDate, String numberAndDate) {
this.sheetNumber = new SimpleIntegerProperty(sheetNumber);
this.sheetDate = new SimpleObjectProperty<>(sheetDate);
this.numberAndDate = new SimpleStringProperty(numberAndDate);
}
public Integer getSheetNumber() {
return sheetNumber.get();
}
public void setSheetNumber(Integer value) {
sheetNumber.set(value);
}
public IntegerProperty SheetNumberProperty() {
return sheetNumber;
}
public Date getSheetDate() {
return sheetDate.get();
}
public void setSheetDate(Date value) {
sheetDate.set(value);
}
public ObjectProperty SheetDateProperty() {
return sheetDate;
}
public String getNumberAndDate() {
return numberAndDate.get();
}
public void setNumberAndDate(String value) {
numberAndDate.set(value);
}
public StringProperty NumberAndDateProperty() {
return numberAndDate;
}
}
Here is part of the controller:
public class StartGUIController implements Initializable {
Connection conn = DbConnection.Connect();
ObservableList<FiseDetails> data = FXCollections.observableArrayList();
PreparedStatement preparedStatement = null;
ResultSet rs = null;
#FXML
private TextField txt_SheetNumber;
#FXML
private DatePicker sheetDate;
#FXML
void generateSheet(ActionEvent event) throws SQLException {
Integer id = Integer.parseInt(txt_SheetNumber.getText());
LocalDate selectedDate = sheetDate.getValue();
Date date = Date.valueOf(selectedDate);
LocalDate strgDate = sheetDate.getValue();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM- yyyy");
String formatedDate = (strgDate).format(formatter);
String last7 = formatedDate.substring(formatedDate.length() - 7);
String numberAndDate = txt_SheetNumber.getText() + " " + last7;
try (PreparedStatement checkNumberAndDateExists = conn.prepareStatement("SELECT 1 FROM SHEETSDB WHERE NUMBERANDDATE = ?")) {
checkNumberAndDateExists.setString(1, numberAndDate);
try (ResultSet result = checkNumberAndDateExists.executeQuery()) {
if (result.next()) {
Alert confirmation = new Alert(AlertType.INFORMATION);
confirmation.setTitle("Fisa existenta");
confirmation.setHeaderText(null);
confirmation.setContentText("Fisa " + txt_SheetNumber.getText() + "/" + sheetDate.getValue() + " exista");
confirmation.showAndWait();
} else {
String query = "INSERT INTO SHEETSDB (ID, SHEETDATE, NUMBERANDDATE) VALUES (?,?,?)";
preparedStatement = null;
try {
preparedStatement = conn.prepareStatement(query);
preparedStatement.setInt(1, id);
preparedStatement.setDate(2, date);
preparedStatement.setString(26, numberAndDate);
} catch (SQLException e) {
System.out.println(e);
} finally {
preparedStatement.execute();
preparedStatement.close();
}
Alert confirmation = new Alert(AlertType.INFORMATION);
confirmation.setTitle("Finalizare generare fisa");
confirmation.setHeaderText(null);
confirmation.setContentText("Fisa " + txt_SheetNumber.getText() + "/" + sheetDate.getValue() + " a fost creata cu succes");
confirmation.showAndWait();
TableData();
}
}
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
//here I have some code that does not have any impact on my problem
}
My question is how can I efficiently check if the sheet number already exists in the database for that month without having to create the extra column. Let me know if you think that the actual solution is the best one, as the extra column is the only column that is unique, so that's the column I also use when I need to remove a row from the database.
Also I can't think of a solution to auto increment the sheet number and set it to the textfield, like check the last sheet number from current month and set it to the "txt_SheetNumber" textfield, if none set it to 1, so whenever I initialize the app to have already the sheet number in the textfield. If you can help me with that also would be much appreciated.
This is my first time working with Java or any other programming language, so feel free to comment on any aspect. The application is for me only to make my work easier.
After some digging, I found a solution for the 2nd problem. Let me know if I shall improve it.
int lastId() {
int newSheetNumber=0;
String query = "SELECT MAX(ID) FROM SHEETSDB WHERE MONTH(`SHEETDATE`)=MONTH(NOW()) AND YEAR(`SHEETDATE`)=YEAR(NOW())";
try {
preparedStatement = conn.prepareStatement(query);
rs = preparedStatement.executeQuery();
if (!rs.next()) {
newSheetNumber = 1;
}else {
newSheetNumber = rs.getInt(1) + 1;
}
preparedStatement.close();
rs.close();
//System.out.println("The new sheet is: " + newSheetNumber);
} catch (SQLException ex) {
System.err.println("Error " + ex);
}
return newSheetNumber;
}

Implementation of ODCITableDescribe in a Java Stored Procedure

The current question is the second part of this ODCI related question.
I have implemented a collection type in Oracle SQL which is practically defined as a type and a table of that type.
CREATE TYPE row_type AS OBJECT
(
C1 VARCHAR2(50),
C2 VARCHAR2(50),
C3 VARCHAR2(50)
);
/
CREATE TYPE row_type_set AS TABLE OF row_type;
Also, I have defined an ODCI type with its implementation as a Java Stored Procedure within database:
SQL:
CREATE OR REPLACE TYPE ODCIImpl AS OBJECT (
key INTEGER,
STATIC FUNCTION ODCITableStart(sctx OUT ODCIImpl, cur SYS_REFCURSOR)
RETURN NUMBER
AS LANGUAGE JAVA
NAME 'ODCIImpl.ODCITableStart(oracle.sql.STRUCT[], java.sql.ResultSet) return java.math.BigDecimal',
MEMBER FUNCTION ODCITableFetch(self IN OUT ODCIImpl, nrows IN NUMBER,
outSet OUT row_type_set) RETURN NUMBER
AS LANGUAGE JAVA
NAME 'ODCIImpl.ODCITableFetch(java.math.BigDecimal, oracle.sql.ARRAY[]) return java.math.BigDecimal',
MEMBER FUNCTION ODCITableClose(self IN ODCIImpl) RETURN NUMBER
AS LANGUAGE JAVA
NAME 'ODCIImpl.ODCITableClose() return java.math.BigDecimal'
);
/
Java Stored Procedure:
import java.io.*;
import java.util.*;
import oracle.sql.*;
import java.sql.*;
import java.math.BigDecimal;
import oracle.CartridgeServices.*;
// stored context type
public class StoredCtx
{
ResultSet rset;
public StoredCtx(ResultSet rs) { rset=rs; }
}
// implementation type
public class ODCIImpl implements SQLData
{
private BigDecimal key;
final static BigDecimal SUCCESS = new BigDecimal(0);
final static BigDecimal ERROR = new BigDecimal(1);
final static int MAX_COLUMNS = 3;
// Implement SQLData interface.
String sql_type;
public String getSQLTypeName() throws SQLException
{
return sql_type;
}
public void readSQL(SQLInput stream, String typeName) throws SQLException
{
sql_type = typeName;
key = stream.readBigDecimal();
}
public void writeSQL(SQLOutput stream) throws SQLException
{
stream.writeBigDecimal(key);
}
// type methods implementing ODCITable interface
static public BigDecimal ODCITableStart(STRUCT[] sctx,ResultSet rset)
throws SQLException
{
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
// create a stored context and store the result set in it
StoredCtx ctx=new StoredCtx(rset);
// register stored context with cartridge services
int key;
try {
key = ContextManager.setContext(ctx);
} catch (CountException ce) {
return ERROR;
}
// create a ODCIImpl instance and store the key in it
Object[] impAttr = new Object[1];
impAttr[0] = new BigDecimal(key);
StructDescriptor sd = new StructDescriptor("ODCIIMPL",conn);
sctx[0] = new STRUCT(sd,conn,impAttr);
return SUCCESS;
}
public BigDecimal ODCITableFetch(BigDecimal nrows, ARRAY[] outSet)
throws SQLException
{
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
// retrieve stored context using the key
StoredCtx ctx;
try {
ctx=(StoredCtx)ContextManager.getContext(key.intValue());
} catch (InvalidKeyException ik ) {
return ERROR;
}
// get the nrows parameter, but return up to 10 rows
int nrowsval = nrows.intValue();
// create a vector for the fetched rows
Vector v = new Vector(nrowsval);
int i=0;
StructDescriptor outDesc =
StructDescriptor.createDescriptor("ROW_TYPE", conn);
Object[] out_attr = new Object[MAX_COLUMNS];
ResultSetMetaData rsmd = ctx.rset.getMetaData();
int columnsNumber = rsmd.getColumnCount();
while(nrowsval>0 && ctx.rset.next()){
for(int j = 0; j < columnsNumber; j++) {
if(j == MAX_COLUMNS)
break;
out_attr[j] = (Object)ctx.rset.getString(j+1);
}
v.add((Object)new STRUCT(outDesc, conn, out_attr));
i+=1;
nrowsval-=1;
}
// return if no rows found
if(i==0) return SUCCESS;
// create the output ARRAY using the vector
Object out_arr[] = v.toArray();
ArrayDescriptor ad = new ArrayDescriptor("ROW_TYPE_SET",conn);
outSet[0] = new ARRAY(ad,conn,out_arr);
return SUCCESS;
}
public BigDecimal ODCITableClose() throws SQLException {
// retrieve stored context using the key, and remove from ContextManager
StoredCtx ctx;
try {
ctx=(StoredCtx)ContextManager.clearContext(key.intValue());
} catch (InvalidKeyException ik ) {
return ERROR;
}
// close the result set
Statement stmt = ctx.rset.getStatement();
ctx.rset.close();
if(stmt!=null) stmt.close();
return SUCCESS;
}
}
After all of this, I've implemented a pipelined function that can be called using a cursor.
CREATE OR REPLACE FUNCTION Exec_Remote_SQL_JSP(p SYS_REFCURSOR) RETURN row_type_set
PIPELINED USING ODCIImpl;
/
My question now is how can we implement an ODCITableDescribe method in a Java Stored Procedure in order to output any data type in the emulated table? First of all, is it possible at all? I didn't seem to find any relevant information about this on the Oracle documentation from here and here
If it is possible to do so, it is self-explainable that we do not need anymore the collection types mentioned at the beginning. The emulated table should have the same size and data types as the table from which we intend to select information.

Working with ResultSets in Java

I've ran into a problem of having to run a number of different queries on the DB (different return types, different number of columns, etc).
While writing that i started to wonder if there's a proper way of writing a helper function.
It seemed that it's really easy to write a function that returns a ResultSet.
However since it a) doesn't close connection b) doesn't close the result set it seems as a possibly working, but improper solution. Is there any place to dump in all results so that they can be returned safely.
(Only thing i could come up with, is just returning a 2D string array (after converting all data to strings) and then converting it all back)
EDIT : Sorry for not writing clear, was wondering if there's any way to just store the result of the query as is (don't need to modify it) without writing a separate method for every possible return type.
The idea behind a 2d string list is being able to store the query values as is.
Col1 Row1 | Col2 Row1 | Col3 Row1
Col1 Row2 | Col2 Row2 | Col3 Row2
EDIT 2 Thank you for replies, i guess i'll just write a small parser for it.
You shouldn't be returning resultSets, you should read the results from the resultset into some kind of container object. A ResultSet is a wrapper around a database cursor, it goes away when the connection closes. It's something you read from and close right away, not something you can pass around your application.
Look at how spring-jdbc does it. You implement a resultSetMapper that is passed to the method on the JdbcTemplate.
Several observations:
You don't need to use Spring to use spring-jdbc. However, I see very little value in reimplementing this stuff yourself.
It's not the job of the code that reads the ResultSet to open and close connections, that needs to be elsewhere.
I'd recommend looking at Spring JDBC. Don't write such a thing yourself. It's already been done, and quite well.
For example, I don't like your idea of returning a List of Strings. You lose a lot of info that way. I'd return a Map of Lists (column view) or List of Maps (row view).
If you must, here are some database utilities that would get you started.
package persistence;
import java.sql.*;
import java.util.*;
/**
* util.DatabaseUtils
* User: Michael
* Date: Aug 17, 2010
* Time: 7:58:02 PM
*/
public class DatabaseUtils {
/*
private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DEFAULT_URL = "jdbc:oracle:thin:#host:1521:database";
private static final String DEFAULT_USERNAME = "username";
private static final String DEFAULT_PASSWORD = "password";
*/
/*
private static final String DEFAULT_DRIVER = "org.postgresql.Driver";
private static final String DEFAULT_URL = "jdbc:postgresql://localhost:5432/party";
private static final String DEFAULT_USERNAME = "pgsuper";
private static final String DEFAULT_PASSWORD = "pgsuper";
*/
private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/party";
private static final String DEFAULT_USERNAME = "party";
private static final String DEFAULT_PASSWORD = "party";
public static void main(String[] args) {
long begTime = System.currentTimeMillis();
String driver = ((args.length > 0) ? args[0] : DEFAULT_DRIVER);
String url = ((args.length > 1) ? args[1] : DEFAULT_URL);
String username = ((args.length > 2) ? args[2] : DEFAULT_USERNAME);
String password = ((args.length > 3) ? args[3] : DEFAULT_PASSWORD);
Connection connection = null;
try {
connection = createConnection(driver, url, username, password);
DatabaseMetaData meta = connection.getMetaData();
System.out.println(meta.getDatabaseProductName());
System.out.println(meta.getDatabaseProductVersion());
String sqlQuery = "SELECT PERSON_ID, FIRST_NAME, LAST_NAME FROM PERSON ORDER BY LAST_NAME";
System.out.println("before insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
connection.setAutoCommit(false);
String sqlUpdate = "INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES(?,?)";
List parameters = Arrays.asList("Foo", "Bar");
int numRowsUpdated = update(connection, sqlUpdate, parameters);
connection.commit();
System.out.println("# rows inserted: " + numRowsUpdated);
System.out.println("after insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
} catch (Exception e) {
rollback(connection);
e.printStackTrace();
} finally {
close(connection);
long endTime = System.currentTimeMillis();
System.out.println("wall time: " + (endTime - begTime) + " ms");
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
Class.forName(driver);
if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0)) {
return DriverManager.getConnection(url);
} else {
return DriverManager.getConnection(url, username, password);
}
}
public static void close(Connection connection) {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement st) {
try {
if (st != null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(Connection connection) {
try {
if (connection != null) {
connection.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static List<Map<String, Object>> map(ResultSet rs) throws SQLException {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
try {
if (rs != null) {
ResultSetMetaData meta = rs.getMetaData();
int numColumns = meta.getColumnCount();
while (rs.next()) {
Map<String, Object> row = new HashMap<String, Object>();
for (int i = 1; i <= numColumns; ++i) {
String name = meta.getColumnName(i);
Object value = rs.getObject(i);
row.put(name, value);
}
results.add(row);
}
}
} finally {
close(rs);
}
return results;
}
public static List<Map<String, Object>> query(Connection connection, String sql, List<Object> parameters) throws SQLException {
List<Map<String, Object>> results = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters) {
ps.setObject(++i, parameter);
}
rs = ps.executeQuery();
results = map(rs);
} finally {
close(rs);
close(ps);
}
return results;
}
public static int update(Connection connection, String sql, List<Object> parameters) throws SQLException {
int numRowsUpdated = 0;
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
int i = 0;
for (Object parameter : parameters) {
ps.setObject(++i, parameter);
}
numRowsUpdated = ps.executeUpdate();
} finally {
close(ps);
}
return numRowsUpdated;
}
}
You can write helper functions that parse a ResultSet and convert it into an ArrayList or an array or even the fields of an object. For instance, lets say you have a table of orders and then a query returns all of the rows of that table for a particular user (customer). We could then do something like this:
static List<Order> parseOrder(ResultSet rs) {
ArrayList<Order> orderList = new ArrayList<>();
while(rs.next() ) {
Order order = new Order();
order.setID(rs.getInt(1));
order.setCustomerID(rs.getInt(2));
order.setItemName(rs.getString(3));
orderList.add(order);
}
return orderList;
}
Simply turning the result set into an array of an array of Objects would be more general, but probably less useful.
I would leave it up to the calling function to close this ResultSet and possible the PreparedStatement (or Statement) and database connection.

preparedstatement with sql query referencing multiple tables

So I am trying to find an example online about creating a preparedStatement that has an sql query referencing multiple tables.
For e.g. The examples I've encountered so far are always
e.g.
s = conn.prepareStatement ("DELETE FROM Users WHERE id_user = ?");
s.setInt (1, 2);
where there is only one table involved, and the method exists in the same class of the database table. E.g. User.class , user table in database.
The query that I have requires me to set the place holder from another table/class. In this case, my method exists in the User.class, however, it requires a the binding from a Group object.
SELECT DISTINCT *
FROM usuarios
WHERE NOT EXISTS
(SELECT * FROM usuarios_grupos
WHERE usuarios_grupos.id_grupo = ?
AND usuarios_grupos.id_usuario = usuarios.id_usuario);
Will the method be the following:
public List<Usuarious> list(Grupos groups) throws DAOExceptions {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Usuarious> users = new ArrayList<Usuarious>();
try {
connection = daoFactory.getConnection();
preparedStatement = connection.prepareStatement(SQL_LIST_ALL);
preparedStatement.setInt(1, groups.getId_grupo());
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
users.add(mapUser(resultSet));
}
} catch (SQLException e) {
throw new DAOExceptions(e);
} finally {
close(connection, preparedStatement, resultSet);
}
return users;
}
or will it be written differently?? because I seem to be getting a NPE with this, and from the examples I've seen online. The query always reference 1 table. Is what I'm doing here wrong?
okay here is my method for groups.getId_grupo(), which exists in my Group.class:
public class Grupos {
Integer id_grupo;
String descricao;
public Grupos() {
}
public Grupos(Integer id_grupo, String descricao) {
this.id_grupo = id_grupo;
this.descricao = descricao;
}
public Grupos(Integer id_grupo) {
this.id_grupo = id_grupo;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public Integer getId_grupo() {
return id_grupo;
}
public void setId_grupo(Integer id_grupo) {
this.id_grupo = id_grupo;
}
}
I am calling my List list(Grupos groups) method in my ManagedBean
public class UsuariousGruposBean implements Serializable {
private Usuarious user = new Usuarious();
private Grupos grps = new Grupos();
private UsuariousGrupos userGroups = new UsuariousGrupos();
protected final UsuariousDAO userDAO = daoFactory.getUserDAO();
protected final GruposDAO grpDAO = daoFactory.getGruposDAO();
protected final UsuariousGruposDAO userGrpDAO = daoFactory.getUsuariousGruposDAO();
private List<Usuarious> listOfUsuarios;
private List<Grupos> listOfGrps;
private List<UsuariousGrupos> listOfUserGroups;
public UsuariousGruposBean() {
}
public List<Usuarious> getListOfUsuarios() throws DAOExceptions {
List<Usuarious> usuariosList = userDAO.list(grps);
listOfUsuarios = usuariosList;
return listOfUsuarios;
}
First instance in your code can throw NPE is at:
preparedStatement = connection.prepareStatement(SQL_LIST_ALL);
if your connection is null, your connection factory didnt return you one, check if you have a valid connection
Second place :
groups.getId_grupo()
Check if your groups is null or not
If these are not the reasons then please post your stacktrace.
The stack trace of your NPE should help tell you where the issue is (line #, etc.). From what I can tell, your SQL and the way you are calling it is all valid.
Is it possible that you're receiving a null groups parameter, such that calling groups.getId_grupo() is throwing the NPE?

Categories