I'm using Oracle 19c database. And HOMESQUAD_EMPLOYEE is table with columns : EMP_ID,EMP_NAME,EMP_MOBILE_NO,EMP_PASSWORD with VARCHAR2(50).
I'm trying to retrieve the row with given EMP_MOBILE_NO in Java using ResultSet object .
Connection is established successfully. PreparedStatement is getting executed successfully,ResultSet is not null but ResultSet.next() is null.
The same query is getting executed and I'm getting required row.
Here's the Code and its output.
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//Loading Driver
Class.forName("oracle.jdbc.driver.OracleDriver");
//Loading Connection
con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521/orcl", dbUsername, dbPassword);
//Executing query;
System.out.println("Connection Established");
//Object to store result
items = new ArrayList < Object > ();
Map properties={ActionType=ProcessLogin, mobileNo=8308856606};
queryString=buildLoginQuery(properties);
System.out.println("Query: " + queryString);
if (queryString != null && !queryString.trim().equals("")) {
System.out.println("Into P Statement If Loop");
pstmt = con.prepareStatement(queryString);
System.out.println("StateMent Prepared: " + pstmt.toString());
rs = pstmt.executeQuery();
System.out.println("Query Executed");
System.out.println("Result Set rs.next():" + rs.next()); //Error Point
while (rs != null && rs.next()) {
items.add(constructLoginProps(rs));
}
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
}
} catch (Exception e) {
System.out.println("Exception Occured in aDBExecute:" + e.getMessage());
}
//constructLoginProps Function
private HomesquadEmployee constructLoginProps(ResultSet rs) {
HomesquadEmployee vo = new HomesquadEmployee();
try {
if (rs.getString("EMP_PASSWORD") != null) {
vo.setEmpPassword(rs.getString("EMP_PASSWORD"));
}
if (rs.getString("EMP_ID") != null) {
vo.setEmpId(rs.getString("EMP_ID"));
}
if (rs.getString("EMP_NAME") != null) {
vo.setEmpName(rs.getString("EMP_NAME"));
}
if (rs.getString("EMP_MOBILE_NO") != null) {
vo.setEmpMobileNo(rs.getString("EMP_MOBILE_NO"));
}
} catch (Exception e) {
System.out.println("Exception Occured in buildLoginQuery: " + e.getMessage());
}
return (vo);
}
//HomesquadEmployee Class
public class HomesquadEmployee {
private String empId;
private String empName;
private String empMobileNo;
private String empPassword;
public HomesquadEmployee() {}
public HomesquadEmployee(String empId, String empName, String empMobileNo, String empPassword) {
this.empId = empId;
this.empName = empName;
this.empMobileNo = empMobileNo;
this.empPassword = empPassword;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpMobileNo() {
return empMobileNo;
}
public void setEmpMobileNo(String empMobileNo) {
this.empMobileNo = empMobileNo;
}
public String getEmpPassword() {
return empPassword;
}
public void setEmpPassword(String empPassword) {
this.empPassword = empPassword;
}
}
//build Query Function
private String buildLoginQuery(Map properties) throws Exception {
String mobileNo="";
String password="";
queryString="SELECT * FROM HOMESQUAD_EMPLOYEE ";
if(properties!=null && (String)properties.get("mobileNo")!=null) {
mobileNo=((String)properties.get("mobileNo")).trim();
queryString=queryString+" WHERE EMP_MOBILE_NO = "+"'"+mobileNo.toUpperCase()+"'";
}
return(queryString);
}
Output:
Connection Established.
Query: SELECT * FROM HOMESQUAD_EMPLOYEE WHERE EMP_MOBILE_NO = '8308856606'
Into P Statement If Loop
StateMent Prepared: oracle.jdbc.driver.OraclePreparedStatementWrapper#514f51cf
Query Executed
Result Set rs.next():false
Please help me out.
Related
This question already has answers here:
Why I obtain this "SQLSyntaxErrorException: ORA-00933: SQL command not properly ended" when I try to perform this JDBC query?
(4 answers)
Closed 1 year ago.
I am trying to connect to the Oracle 19c database from Java. Connection is done and successful.
I'm running same query in SQL Develeper and it's working .But I'm getting exception in prepared Statement and executeQuery() in Java. Please help me out.
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try{
//Loading Driver
Class.forName("oracle.jdbc.driver.OracleDriver");
//Loading Connection
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521/orcl",dbUsername,dbPassword);
//Executing query;
System.out.println("Connection Established");
//Object to store result
items=new ArrayList<Object>();
queryString="SELECT * FROM HOMESQUAD WHERE EMP_MOBILE_NO='8308856606';";
System.out.println("Query: "+queryString);
if(queryString != null && !queryString.trim().equals("")) {
System.out.println("Into P Statement If Loop");
pstmt=con.prepareStatement(queryString);
System.out.println("StateMent Prepared: "+pstmt.toString());
rs=pstmt.executeQuery();
System.out.println("Query Executed");
while(rs!=null &&rs.next()) {
items.add(constructLoginProps(rs));
}
if(rs !=null) {
rs.close();
}
if(pstmt!=null) {
pstmt.close();
}
}
}
catch(Exception e) {
System.out.println("Exception Occured in aDBExecute:"+e.getMessage());
}
//constructLoginProps Function
private HomesquadEmployee constructLoginProps(ResultSet rs) {
HomesquadEmployee vo=new HomesquadEmployee();
try {
if(rs.getString("EMP_PASSWORD")!=null) {
vo.setEmpPassword(rs.getString("EMP_PASSWORD"));
}
if(rs.getString("EMP_ID")!=null) {
vo.setEmpId(rs.getString("EMP_ID"));
}
if(rs.getString("EMP_NAME")!=null) {
vo.setEmpName(rs.getString("EMP_NAME"));
}
if(rs.getString("EMP_MOBILE_NO")!=null) {
vo.setEmpMobileNo(rs.getString("EMP_MOBILE_NO"));
}
}
catch(Exception e) {
System.out.println("Exception Occured in buildLoginQuery: "+e.getMessage());
}
return(vo);
}
//HomesquadEmployee Class
public class HomesquadEmployee {
private String empId;
private String empName;
private String empMobileNo;
private String empPassword;
public HomesquadEmployee() {
}
public HomesquadEmployee(String empId, String empName, String empMobileNo, String empPassword) {
this.empId = empId;
this.empName = empName;
this.empMobileNo = empMobileNo;
this.empPassword = empPassword;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpMobileNo() {
return empMobileNo;
}
public void setEmpMobileNo(String empMobileNo) {
this.empMobileNo = empMobileNo;
}
public String getEmpPassword() {
return empPassword;
}
public void setEmpPassword(String empPassword) {
this.empPassword = empPassword;
}
}
Output:
Connection Established
Query:SELECT * FROM HOMESQUAD_EMPLOYEE WHERE EMP_MOBILE_NO ='8308856606';
Into P Statement If Loop
StateMent Prepared: oracle.jdbc.driver.OraclePreparedStatementWrapper#51aeb3e7
Exception Occured in aDBExecute:ORA-00933: SQL command not properly ended
I had that problem once using an oracle database and I solved it by simply removing the semicolon ";" from the end of the query.
in your case you should change this
queryString="SELECT * FROM HOMESQUAD WHERE EMP_MOBILE_NO='8308856606';";
for this
queryString="SELECT * FROM HOMESQUAD WHERE EMP_MOBILE_NO='8308856606'";
I'm working on a sample user-based java web application. When I try to add a user via registration to my database. After capturing the data on the front end, the records get stored as null values
i.e a row of my users table would contain the values (7, null, null, null, null) (using template id(primary-key), f_name, l_name, email, password).
Below are the files I believe could cause possible problems
User.java
package com.ysg.data;
import com.ysg.service.PasswordEncrypter;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
public class User implements Serializable {
private String id;
private String password;
private String firstName;
private String lastName;
private String email;
public User(){
// default
}
public User( String password, boolean isEncrypted, String firstName, String
lastName, String email){
this.password = isEncrypted ? password : encrypt(password);
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
} //getters and setters follow
UserRepository.java
package com.ysg.repository;
import com.ysg.data.User;
import com.ysg.exception.DuplicateItemException;
import com.ysg.exception.RepositoryException;
import com.ysg.util.MySQLHelper;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class UserRepository implements RepositoryInt<User> {
private static final String INSERT = "INSERT INTO ysg.users (f_name, l_name, email, password) values (?, ?, ?, ?)";
private static final String USER_LOGIN = "SELECT * FROM ysg.users WHERE email=? and password=?";
private static final String USER_FETCH = "SELECT * FROM ysg.users WHERE email='";
private static final String FIRSTNAME = "f_name";
private static final String LASTNAME = "l_name";
private static final String EMAIL= "email";
private static final String PASSWORD = "password";
public UserRepository(){
// default
}
#Override
public User login(User obj){
User result = find(obj);
if (result != null) {
return result;
}
return null;
}
#Override
public User register(User obj){
if (obj != null && (find(obj) == null)) {
return add(obj);
}
return null;
}
private User add(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(INSERT);
stmt.setString(1, user.getFirstName());
stmt.setString(2, user.getLastName());
stmt.setString(3, user.getEmail());
stmt.setString(4, user.getPassword());
stmt.execute();
closeStatement(stmt);
return user;
}
catch (SQLException ex) {
if (ex.getMessage().contains("Duplicate")) {
System.out.println("Item with duplicate id already exists in repository");
throw new DuplicateItemException("Item with duplicate id already exists in repository");
}
else {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
}
finally {
closeConnection(conn);
}
}
private User fetch(User user){
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(USER_FETCH + user.getEmail()+ "'");
ResultSet resultSet = stmt.getResultSet();
User result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Failed to fetch item from repository");
throw new RepositoryException(ex);
}
finally {
closeConnection(conn);
}
}
private User find(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(USER_LOGIN);
stmt.setString(1, user.getEmail());
stmt.setString(2, user.getPassword());
ResultSet resultSet = stmt.executeQuery();
User result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
finally {
closeConnection(conn);
}
}
private User marshall(ResultSet result) throws RepositoryException, SQLException{
if (result == null) {
return null;
}
User user = null;
if (result.next()) {
// String id = result.getString(ID);
String password = result.getString(PASSWORD);
String firstName = result.getString(FIRSTNAME);
String lastName = result.getString(LASTNAME);
String email = result.getString(EMAIL);
user = new User(password, true, firstName, lastName, email);
}
return user;
}
private Connection getConnection(){
return MySQLHelper.getConnection();
}
private static void closeStatement(Statement stmt){
if (stmt != null) {
try {
stmt.close();
//stmt = null;
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
}
private void closeConnection(Connection conn){
if (conn != null) {
try {
conn.close();
conn = null;
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
MySQLHelper.java
package com.ysg.util;
import com.ysg.data.User;
import com.ysg.exception.DuplicateItemException;
import com.ysg.exception.RepositoryException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class MySQLHelper {
private static final String INSERT_USER = "INSERT INTO users(f_name, l_name, email, password) values (?, ?, ?, ?)";
private static final String USER_FETCH = "SELECT * FROM users WHERE id='";
private static final String FETCH_ALL = "SELECT * FROM users";
private static final String COUNT_ALL_USERS = "SELECT COUNT(*) FROM users";
private static final String DELETE_ALL = "DELETE FROM users";
private static final String ID = "id";
private static final String EMAIL = "email";
private static final String PASSWORD = "password";
private static final String FIRSTNAME = "f_name";
private static final String LASTNAME = "l_name";
private static final String DS_NAME = "jdbc/sen301DS";
private static Context envCtx;
private static DataSource ds;
static {
try {
Context ctx = new InitialContext();
envCtx = (Context) ctx.lookup("java:/comp/env");
System.out.println(envCtx);
}
catch (Exception ex) {
System.out.println("ConnectionPool will not be available - only direct connection can be used");
}
}
public static List<User> fetch() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(FETCH_ALL);
ResultSet resultSet = stmt.getResultSet();
List<User> result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static User fetch(String id) throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(USER_FETCH + id + "'");
ResultSet resultSet = stmt.getResultSet();
List<User> result = marshall(resultSet);
closeStatement(stmt);
return result.get(0);
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static User add(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(INSERT_USER);
stmt.setString(1, user.getFirstName());
stmt.setString(2, user.getLastName());
stmt.setString(3, user.getEmail());
stmt.setString(4, user.getPassword());
stmt.execute();
closeStatement(stmt);
return user;
}
catch (SQLException ex) {
if (ex.getMessage().contains("Duplicate")) {
System.out.println("Item with duplicate id already exists in repository");
throw new DuplicateItemException("Item with duplicate id already exists in repository");
}
else {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
}
finally {
closeConnection(conn);
}
}
public static int countusers() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(COUNT_ALL_USERS);
ResultSet resultSet = stmt.getResultSet();
int count = 0;
if (resultSet.next()) {
count = resultSet.getInt(1);
}
closeStatement(stmt);
return count;
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static void reset() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate(DELETE_ALL);
closeStatement(stmt);
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
private static List<User> marshall(ResultSet result) throws SQLException{
List<User> list = new ArrayList<User>();
if (result == null) {
return list;
}
while (result.next()) {
String firstName = result.getString(FIRSTNAME);
String lastName = result.getString(LASTNAME);
String email = result.getString(EMAIL);
String passwd = result.getString(PASSWORD);
User user = new User(passwd, true, firstName, lastName, email);
list.add(user);
}
return list;
}
private static DataSource getDataSource(){
DataSource ds = null;
try {
ds = (DataSource) envCtx.lookup(DS_NAME);
}
catch (NamingException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get DataSource");
}
return ds;
}
public static Connection getConnection(){
Connection con = null;
try {
con = getDataSource().getConnection();
}
catch (SQLException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get connection to database server");
}
catch (Exception ex) {
con = getDirectConnection();
}
return con;
}
private static Connection getDirectConnection(){
try {
String conURL = "jdbc:mysql://localhost:3306/ysg?serverTimezone=UTC&useSSL=false&" + "user=sen301&password=sen301";
return DriverManager.getConnection(conURL);
}
catch (SQLException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get direct connection to database server");
}
catch (Exception ex) {
ex.printStackTrace();
throw new RepositoryException(ex);
}
}
private static void closeStatement(Statement stmt){
if (stmt != null) {
try {
stmt.close();
stmt = null;
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
}
private static void closeConnection(Connection conn){
if (conn != null) {
try {
conn.close();
conn = null;
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
I'm trying to write a small java application that returns the details for an employee. Here's my Employee class.
public class Employees {
private int id;
private Date dateofBirth;
private String firstName;
private String lastName;
private enum gender{
M, F;
}
private gender employeeGender;
private Date dateHired;
public String getEmployeeGender() {
return this.employeeGender.name();
}
public void setEmployeeGender(String employeeGender) {
this.employeeGender = gender.valueOf(employeeGender);
}
/*Getters, setters omitted*/
Here's my DAO class
public class EmployeeDao {
final String TABLE_EMPLOYEES = "employees";
final String COLUMN_EMPLOYEES_ID = "emp_no";
final String COLUMN_EMPLOYEES_DOB = "birth_date";
final String COLUMN_EMPLOYEES_FIRST_NAME = "first_name";
final String COLUMN_EMPLOYEES_LAST_NAME = "last_name";
final String COLUMN_EMPLOYEES_GENDER = "gender";
final String COLUMN_EMPLOYEES_HIRE_DATE = "hire_date";
final String QUERY_EMPLOYEES = "SELECT * FROM " + TABLE_EMPLOYEES + " WHERE " + COLUMN_EMPLOYEES_ID + " = ?";
public Employees getEmployeeDetails(int employeeId) {
Employees employee = new Employees();
try (DbConnection dbConnection = new DbConnection();
Connection databaseConnection = dbConnection.getConn();
PreparedStatement selectFromEmployees = databaseConnection.prepareStatement(QUERY_EMPLOYEES)) {
selectFromEmployees.setInt(1, employeeId);
try (ResultSet result = selectFromEmployees.executeQuery()) {
if (result.next() == false) {
System.out.println("Empty Resultset");
}
while (result.next()) {
employee.setId(result.getInt(COLUMN_EMPLOYEES_ID));
employee.setFirstName(result.getString(COLUMN_EMPLOYEES_FIRST_NAME));
employee.setLastName(result.getString(COLUMN_EMPLOYEES_LAST_NAME));
employee.setDateofBirth(result.getDate(COLUMN_EMPLOYEES_DOB));
employee.setEmployeeGender(result.getString(COLUMN_EMPLOYEES_GENDER));
employee.setDateHired(result.getDate(COLUMN_EMPLOYEES_HIRE_DATE));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return employee;
}
}
But when I try to run the app in main method like this, I get an output with null values.
public static void main(String[] args) {
EmployeeDao employeeDao = new EmployeeDao();
Employees employees = employeeDao.getEmployeeDetails(39256);
System.out.println(employees.getId() + " \n" + employees.getFirstName() + " \n" + employees.getLastName() + " \n" + employees.getDateofBirth() + " \n" + employees.getDateHired());
}
This is the output.
This is how the corresponding row looks like in the database
You should not call next twice, since it will move the cursor forward again. Try this:
if (result.next() == false) {
System.out.println("Empty Resultset");
} else {
employee.setId(result.getInt(COLUMN_EMPLOYEES_ID));
employee.setFirstName(result.getString(COLUMN_EMPLOYEES_FIRST_NAME));
employee.setLastName(result.getString(COLUMN_EMPLOYEES_LAST_NAME));
employee.setDateofBirth(result.getDate(COLUMN_EMPLOYEES_DOB));
employee.setEmployeeGender(result.getString(COLUMN_EMPLOYEES_GENDER));
employee.setDateHired(result.getDate(COLUMN_EMPLOYEES_HIRE_DATE));
}
Calling ResultSet#next moves the cursor forward a row, so your if condition loses the first row. Since you know your query can return at most one row, you don't need the while loop at all, however:
public Employees getEmployeeDetails(int employeeId) throws SQLException {
Employees employee = null;
try (DbConnection dbConnection = new DbConnection();
Connection databaseConnection = dbConnection.getConn();
PreparedStatement selectFromEmployees =
databaseConnection.prepareStatement(QUERY_EMPLOYEES)) {
selectFromEmployees.setInt(1, employeeId);
try (ResultSet result = selectFromEmployees.executeQuery()) {
if (result.next()) {
employee = new Employees();
employee.setId(result.getInt(COLUMN_EMPLOYEES_ID));
employee.setFirstName(result.getString(COLUMN_EMPLOYEES_FIRST_NAME));
employee.setLastName(result.getString(COLUMN_EMPLOYEES_LAST_NAME));
employee.setDateofBirth(result.getDate(COLUMN_EMPLOYEES_DOB));
employee.setEmployeeGender(result.getString(COLUMN_EMPLOYEES_GENDER));
employee.setDateHired(result.getDate(COLUMN_EMPLOYEES_HIRE_DATE));
}
}
}
return employee;
}
No need to add extra result.next() comparison.
if (result.next() == false) {
System.out.println("Empty Resultset");
}
while (result.next()){
}
while will execute only if there are any rows.
Check the size of list generated before using to check if it contains value or not.
Why is this unit test failing when I run it in Debug mode using a break-point at the line
while (rs.next()) {.
It will exit the loop after the first iteration despite the instruction in the test.
Mockito.when(mockResultSet.next()).thenReturn(true, true, false);
this unit test works fine when running it in normal mode.
note: I am using Intellij, testNG.
Class
public class ProjectDao {
private static Logger LOG = LogManager.getLogger(ProjectDao.class);
private DataSource dataSource;
private int id;
private String name;
// For Testing
public ProjectDao(DataSource dataSource) {
this.dataSource = dataSource;
}
public ProjectDao() {
dataSource = Database.getDataSource();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Project> getProjects() throws Exception {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
String SQL = "SELECT project.id, project.name FROM cicd.project";
List<Project> projects = new ArrayList<>();
try {
conn = dataSource.getConnection();
ps = conn.prepareStatement(SQL);
rs = ps.executeQuery();
while (rs.next()) {
Project p = new Project();
p.setId(rs.getInt("id"));
p.setName(rs.getString("name"));
projects.add(p);
}
LOG.debug("found: " + projects);
return projects;
} catch (SQLException e) {
LOG.error("Error: " + e.getMessage());
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
LOG.error("Error closing resultset: " + e.getMessage());
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
LOG.error("Error closing PreparedStatement: " + e.getMessage());
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
LOG.error("Error closing connection: " + e.getMessage());
e.printStackTrace();
}
}
}
return projects;
}
Test class
#PrepareForTest(ProjectDao.class)
public class ProjectDaoTests {
private static Logger LOG = LogManager.getLogger(ProjectDaoTests.class);
List<Project> projects;
Project projectA = new Project();
Project projectB = new Project();
#Mock
DataSource mockDataSource;
#Mock
Connection mockConn;
#Mock
PreparedStatement mockPreparedStmnt;
#Mock
ResultSet mockResultSet;
#BeforeTest(groups = "ut")
public void initMocks() throws IOException, SQLException {
MockitoAnnotations.initMocks(this);
when(mockDataSource.getConnection()).thenReturn(mockConn);
when(mockDataSource.getConnection(anyString(), anyString())).thenReturn(mockConn);
doNothing().when(mockConn).commit();
when(mockConn.prepareStatement(anyString())).thenReturn(mockPreparedStmnt);
when(mockPreparedStmnt.executeQuery()).thenReturn(mockResultSet);
projects = new ArrayList<>();
}
#Test(groups = "ut")
public void testProjects() throws Exception {
projectA.setId(1);
projectA.setName("projectA");
projectB.setId(2);
projectB.setName("projectB");
projects.add(projectA);
projects.add(projectB);
Mockito.when(mockResultSet.next()).thenReturn(true, true, false);
Mockito.when(mockResultSet.getInt("id")).thenReturn(projectA.getId(), projectB.getId());
Mockito.when(mockResultSet.getString("name")).thenReturn(projectA.getName(), projectB.getName());
ProjectDao projectDao = new ProjectDao(mockDataSource);
List<Project> projectsList = projectDao.getProjects();
Assert.assertEquals(projectsList.size(), 2);
Assert.assertEquals(projectsList.get(0).getId(), projectA.getId());
Assert.assertEquals(projectsList.get(0).getName(), projectA.getName());
Assert.assertEquals(projectsList.get(1).getId(), projectB.getId());
Assert.assertEquals(projectsList.get(1).getName(), projectB.getName());
}
I'm making a Timetable scheduler as a final year project. For the last two days, I'm getting an OutOfMemoryException. I have read a lot about the exception, and tried to increase the memory alloted through the -Xms and -Xmx options. None of these seem to work for me.
I profiled the project, and found that the maximum space was consumed by hashmap objects, and also by the MySQL connection. I have used a static connection as follows
public final class Connector
{
private static Connector connector;
Connection con;
String driverName;
String dbname;
String username;
String password;
String connString;
private Connector(){
driverName = "com.mysql.jdbc.Driver";
dbname = "timegen";
username = "root";
password = "root";
connString = "jdbc:mysql://localhost:3306/" + dbname;
openConnection();
}
public void openConnection(){
try{
Class.forName(driverName);
con = DriverManager.getConnection(connString, username, password);
} catch(Exception e){
System.out.println(e);
}
}
public void terminateConnection(){
try{
con.close();
} catch(Exception e){
System.out.println(e);
}
}
public static Connector createConnection() {
if (connector == null){
connector = new Connector();
}
return connector;
}
public Connection getCon() {
return con;
}
public String getConnString() {
return connString;
}
public void setConnString(String connString) {
this.connString = connString;
}
}
This is the code for a class named MasterData, which is extended by all other classes that access the database
public class MasterData{
static Connector con;
static Statement st;
MasterData(){
try {
con = Connector.createConnection();
st = con.getCon().createStatement();
} catch (SQLException ex) {
Logger.getLogger(MasterData.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Statement createStatement() throws SQLException{
Statement st = con.getCon().createStatement();
return st;
}
public void closeConnection(){
con.terminateConnection();
}
}
An example of a class that uses this
public class Teacher extends MasterData{
int teacherid;
String teachername;
String subject;
String post;
#Override
public String toString() {
return "Teacher{" + "teacherid=" + teacherid + ", teachername=" + teachername + ",
post=" + post + ", subject=" + subject + '}';
}
public Teacher(int teacherid, String teachername,String subject, String post) {
this.teacherid = teacherid;
this.teachername = teachername;
this.subject = subject;
this.post = post;
}
public Teacher(String teachername) {
this.teachername = teachername;
}
public Teacher(){}
public String display(){
String s ="\nTeacher name = " + teachername
+ "\nSubject = " + subject
+ "\nPost = "+post;
return s;
}
public ArrayList<String> getSubjectTeachers(String s){
ArrayList<String> teachers = new ArrayList<String>();
try{
ResultSet rs = st.executeQuery("select teachername from teacher where
subject='"+s+"';");
while(rs.next()){
teachers.add(rs.getString(1));
}
}catch(Exception e){e.printStackTrace();}
return teachers;
}
public List<Teacher> getFree()
{
List<Teacher> lst = new ArrayList<Teacher>();
try{
ResultSet rs = st.executeQuery("select * from teacher where teacherid not
in(select classteacher from division where classteacher!=null)");
while(rs.next())
{
lst.add(new
Teacher(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4)));
}
}catch(Exception e ){e.printStackTrace();}
return lst;
}
public int getTeacherid() {
return teacherid;
}
public void setTeacherid(int teacherid) {
this.teacherid = teacherid;
}
public String getTeachername() {
return teachername;
}
public void setTeachername(String teachername) {
this.teachername = teachername;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public boolean checkDuplicate(){
try{
ResultSet rs = st.executeQuery("select * from teacher where
teachername='"+teachername+"';");
if(rs.next())
return true;
}catch(Exception e){e.printStackTrace();}
return false;
}
public boolean insert(){
int t;
try{
t = st.executeUpdate("insert into teacher(teachername,subject,post)
values('"+teachername+"','"+subject+"','"+post+"');");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
public boolean delete(){
int t;
try{
new AssignedTeacher().deleteTeacher(teacherid);
t = st.executeUpdate("delete from teacher where teacherid="+teacherid+";");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
public boolean update(){
int t;
try{
t = st.executeUpdate("update teacher set teachername = '"+teachername+"',
subject='"+subject+"', post='"+post+"' where teacherid="+teacherid+";");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
}
My intention was to create a single static connection for the entire program. It seems to work well. But is this the possible cause of the problem?
Try to set these parameters as well:
-XX:PermSize
-XX:MaxPermSize
It looks like you are creating too many Connections.
You may verify whether or not your connection is valid in your openConnection method You also may use some Connection Pool.
EDIT:
It seems to me that you've tried to implement Active record pattern because there are insert, delete, update and getSubjectTeachers methods. Anyway, its is not always a good idea to extend Teacher from MasterData. As a side effect, new connections will be created for each instance of MasterData. static Connection con would be reassigned to new object but previous Connection will not be ever closed. Same holds with MasterData#createStatement.
Also, as greedybuddha pointed out, make sure that your HashMap are not reassigned in the same manner.