Java General Error On Insert...??? - java

I am trying to do an Insert, Update and Delete on a table in MS Access. Everything works fine
for a SELECT statement. But when doing the other three operations, I don't seem to get any
errors, but the actions are not reflected on to the DB. Please help...
THe INSERT statement is as follows:
PreparedStatement ps = con.prepareStatement("INSERT INTO Student VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1,1);
ps.setString(2,"ish");
ps.setInt(3,100);
ps.setInt(4,100);
ps.setInt(5,100);
ps.setInt(6,300);
ps.setInt(7,100);
ps.setString(8,"A");
ps.executeUpdate();
Also may I know why PreparedStatement is used except for SELECT statement...
I get this error:
Exception in thread "main" java.sql.SQLException: General error
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6986)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecute(JdbcOdbc.java:3149)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(JdbcOdbcPreparedState
ment.java:216)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeUpdate(JdbcOdbcPrepare
dStatement.java:138)
at Student.main(Student.java:19)
This is my code...
import java.sql.*;
import java.io.*;
class Student {
public static void main(String args[]) throws SQLException, IOException, ClassNotFoundException {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:Student","","");
Statement st = con.createStatement();
PreparedStatement ps = con.prepareStatement("INSERT INTO Student VALUES (?, ?, ?, ?,
?, ?, ?, ?)");
ps.setInt(1,1);
ps.setString(2,"Girish");
ps.setInt(3,100);
ps.setInt(4,100);
ps.setInt(5,100);
ps.setInt(6,300);
ps.setInt(7,100);
ps.setString(8,"A");
ps.executeUpdate();
con.commit();
con.close();
}
}

This can happen when you don't commit/close the connection. Ensure that you're committing the connection after executing the statement and are closing the connection (and statement and resultset) in the finally block of the try block where they are been acquired and executed.
As to why the PreparedStatement is used, it's the common approach to avoid SQL injection attacks and to ease setting fullworthy Java objects like Date, InputStream, etc in a SQL query without the need to convert them to String.

I believe your prepared statement is of the wrong format. The documentation for INSERT INTO (available here: http://msdn.microsoft.com/en-us/library/bb208861(v=office.12).aspx) gives this format:
Single-record append query:
INSERT INTO target [(field1[, field2[, …]])] VALUES (value1[, value2[, …])
You give the format:
INSERT INTO target VALUES (value1[, value2[, …])
edit:
To be more clear I believe you want something like:
PreparedStatement ps = con.prepareStatement("INSERT INTO Student (Year, Name, field3 ...) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
Where Year, Name, field3 ... are the names of the fields you are trying to insert into.

The main reason for using a PreparedStatement is security. Generating a SQL query by concating strings is unsafe as the variable parts may contain SQL statements entered by a user. This would allow to execute statements like DROP TABLE * to the user (see SQL Injection). Theres is is a good idea only to use PreparedStatemnts if the SQL query is not static (doe snot contain variable parts).
Therefore it would be better also to use PreparedStatement for SELECT statements.

Edit :
You try to Insert your Student Primary Key, if it's an Identity column, it will not work.
You need to prepare your statement like this :
PreparedStatement ps = con.prepareStatement("INSERT INTO Student(Field1,Field2,Field3,Field4,Field5,Field6,Field7) VALUES (?, ?, ?, ?, ?, ?, ?)");
Without your Primary Key set, the DB will do it for you.
.
.
.
Original post :
There is a kind of similar question on StackOverflow.
You won't see any result from INSERT queries with Access until you close your Connection properly.
Your code doesn't close any resources, which will surely bring you grief. Call the close methods (in reverse order if there are more than one) in a finally block.
Here is a class DataBaseUtils to help you if needed.
public class DatabaseUtils
{
public static Connection createConnection(String driver, String url, String username, String password)
throws ClassNotFoundException, SQLException
{
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
public static void close(Connection connection)
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (SQLException e)
{
e.printStackTrace(e);
}
}
public static void close(Statement statement)
{
try
{
if (statement != null)
{
statement.close();
}
}
catch (SQLException e)
{
e.printStackTrace(e);
}
}
public static void close(ResultSet rs)
{
try
{
if (rs != null)
{
rs.close();
}
}
catch (SQLException e)
{
e.printStackTrace(e);
}
}
}

Related

Insert into Oracle DB using Java

I am trying to insert values in a table on my oracle server, however, the program keeps running and doesn't execute. This is my code:
This is how I connect to the database:
try {
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#abc.xxx.edu:1521:soeorcl","123",
"123");
} catch (SQLException e) {
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return;
Then I try to insert the values in the table:
try {
PreparedStatement prepareStatement = connection.prepareStatement("INSERT INTO MYTABLE (USERID, USERNAME, EMAILADDRESS, PHONENUMBER, PROFILEPICTURE )"
+ " VALUES (?, ?, ?, ?, ?)");
prepareStatement.setString(1, "10");
prepareStatement.setString(2, "ALI");
prepareStatement.setString(3, "gdgrgrregeg");
prepareStatement.setString(4, "0501977498");
prepareStatement.setNull(5, NULL);
prepareStatement.execute();
} catch (SQLException e) {
System.out.println("IT DOES NOT WORK");
}
The program gets stuck at prepareStatement.execute(); I have already checked the constraints and they work if I manually add them on the oracle server but the above code does not work.
Any ideas? Suggestions?
Try printing the sql string used in your prepared statement and then copy paste it and run it manually. Often times there are some misspellings or missing spaces in the string. In your case it could be an error from the way the statement is written.
I noticed that you need a space before VALUES.

is this actually a resource leak?

I have an "Invitation" object that is modeled in a MySQL database. This object has one list ("treatmentPlanIDsToCopyf") and is maintained in the database with a second table. The method I have written to insert into the main table and then loop through the list and insert records for each item in the list into the second table is below. At the line ps = cn.prepareStatement(sql);Eclipse is giving me a warning that says "Resource leak: 'ps' is not closed at this location". I am closing the prepared statement in the finally clause, so I wanted to know if there really is a resource leak I need to fix. This is my first time using batches with prepared statements, so I wasn't really sure. Thanks.
public void invitationCreate(Connection cn, Invitation invitation) throws SQLException{
PreparedStatement ps = null;
try {
//first insert primary invitation data into the invitation table
String sql = "INSERT INTO invitiation (invitation_code, recipient_email, sender_user_id_fk, date_intived, date_accepted, accepted, recipient_first_name, recipient_last_name) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
ps = cn.prepareStatement(sql);
ps.setString(1, invitation.getInvitationCode());
ps.setString(2, invitation.getRecipientEmail());
ps.setInt(3, invitation.getSenderUserID());
ps.setTimestamp(4, convertLocalTimeDateToTimstamp(invitation.getDateInvited()));
ps.setTimestamp(5, convertLocalTimeDateToTimstamp(invitation.getDateAccepted()));
ps.setBoolean(6, invitation.isAccepted());
ps.setString(7, invitation.getRecipientFirstName());
ps.setString(8, invitation.getRecipientLastName());
int success = ps.executeUpdate();
//now loop through all the treatmentPlanIDs in the invitation that are to be copied into the invitees account when the register
sql = "INSERT INTO invitation_treatment_plans (invitation_code_fk, invitation_treatment_plan_id_fk) VALUES (?, ?)";
ps = cn.prepareStatement(sql);//TODO confirm this if this is actually a resource leak
for(int treatmentPlanID : invitation.getTreatmentPlanIDsToCopy()){
ps.setString(1, invitation.getInvitationCode());
ps.setInt(2, treatmentPlanID);
ps.addBatch();
}
ps.executeBatch();
} finally {
DbUtils.closeQuietly(ps);
}
}
I believe the leak is in the first prepared statement.
After int success = ps.executeUpdate(); you need to close that prepared statement before you assign the variable to a new prepared statement.

How to solve com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'dbo.Table2'

I am inserting data from Java in sql server 2008 DB by reading the data from 1st Database [WBSEDCL].[dbo].[Table1] and then inserting it into second Database [OrganizationMaster].[dbo].[Table2] .
I am using sqljdbc41.jar in my Project.
The code for insertion is as following -
private static Connection getNewDBConnection() {
System.out.println("************************Inside Get DB Connection**************************");
Properties props = new Properties();
if (connection != null)
try {
if (!connection.isClosed())
return connection;
} catch (SQLException e) {
e.printStackTrace();
}
try {
String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String url = "jdbc:sqlserver://142.168.0.112:1733;DatabaseName=OrganizationMasterDB";
String user = "sa";
String password = "Dsdf#123";
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
if (!connection.isClosed())
System.out.println("---------------------DB Connection is Established----------------------");
} catch (ClassNotFoundException e) {
System.out.println("Class Not Found Exception Thrown ");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("SQL Exception Thrown");
e.printStackTrace();
}
return connection;
}
public static void insertDetailsList(PersonalLedger pl) {
Connection conn = getNewDBConnection();
PreparedStatement statement = null;
DetailsList dl = null;
int temp=0,shareAmount=0,shareBalance=0,theiftFundAmount=0,theiftFundInterest=0,GAmtDepo=0,GInterest=0,ShareWithdrawn=0;
String EmNo=null,MemberNo=null, fundString = "Share",status="Unknown",remarks="OtherAmount for Share is The Withdrawn Share Amount",sql=null;
boolean flag= false;
Date sdate = pl.SDate,gdate=pl.Gdate,tdate=pl.TDate;
EmNo = pl.EmNo;
MemberNo = pl.MemberNo;
shareAmount = pl.SAmtDepo;
shareBalance = pl.balance;
ShareWithdrawn = pl.ShareWithdrawn;
theiftFundAmount = pl.TAmtDepo;
theiftFundInterest = pl.TInterest;
GAmtDepo = pl.GAmtDepo;
GInterest = pl.GInterest;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
try{
System.out.println("*****************INSERTING SHARE FUND DETAILS******************");
sql = "INSERT INTO [dbo].[DetailsList] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
statement = conn.prepareStatement(sql);
statement.setString(1, pl.EmNo);
statement.setString(2, pl.MemberNo);
statement.setString(3,"Share");
statement.setLong(4, shareAmount);
/*Date share_date = (Date) formatter.parse(new Date());*/
statement.setLong(5,0);
statement.setLong(6,pl.ShareWithdrawn);
statement.setString(7,"Unknown");
statement.setString(8,"OtherAmount for Share is The Withdrawn Share Amount");
statement.setDate(9, pl.SDate);
statement.setDate(10,null);
statement.setLong(11, shareBalance);
temp = statement.executeUpdate();
if (temp != 0) {
flag = true;
System.out.println("ROW INSERTED SUCCESSFULLY");
}
} catch (Exception e) {
System.out.println("Exception in Insert Details List Items");
e.printStackTrace();
}
}
The problem whenever i run the code i get SQLException. The stackTrace is as below :
Exception in Insert Details List Items
com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'dbo.DetailsList'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:215)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1635)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:426)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:372)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5846)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1719)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:184)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:159)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:315)
at Test.insertDetailsList(Test.java:203)
at Test.main(Test.java:290)
I am completely dumbstruck by this error and could not find any relevant solution for the problem over the net !
Any help will be appreciated. Thanks.
EDIT: After doing some research I moved Table2 to the 1st Database, made necessary changes in connection string and executed the program. The code executed without any Error. So the question remains - 1.why the schema not found earlier when Table2 was under 2nd Database? 2.Is there any configuration required in the Database in order for java to connect with the correct schema and access the table, if so then What ?
Use the [dbname].[dbo].[tblname] query, e.g.select * from [dbname].[dbo].[tblname]
Assuming your INSERT is for Table2 then it should change from
sql = "INSERT INTO [dbo].[DetailsList] VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
to include the target database name. With something like (and you don't need the semi-colon in the query)
sql = "INSERT INTO [OrganizationMaster].[dbo].[DetailsList] VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
Check table DetailsList is exist and user has permission on this table, You can check this my logging into SQL server management studio from that user and try to access the table.

Java prepared statement is not working?

I am writing a database program. But I am stuck with the Java prepared statement. The prepared statement doesn't seems to be working. I spend several hours to make it work but still same result.
String sql = "INSERT into EDMSDATABASE.MESSAGE (title, subject, description, deadline) VALUES (?, ?, ?, ?)";
try (
PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
) {
statement.setString(1, bean.getTitle());
statement.setString(2, bean.getSubject());
statement.setString(3, bean.getDescription());
statement.setString(4, bean.getDeadline());
int affectedRow = statement.executeUpdate();
if(affectedRow == 1) return "Success";
} catch (SQLException e)
{
} finally{
}
Note that bean is a parameter
Are you using 1.7 . If not please use version compatible logic.

Proper Unit Testing in void method in java without mocking

Is there a way to test a method that doesn't return any value without the use of Mockito?
This is the sample method. I'm new in Unit Testing.
public void addMantisData(ArrayList<Mantis> list) {
try {
connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection
.prepareStatement("INSERT INTO mantises (ticketId, startDate, endDate, hours, minutes, " +
"employeeId, timeIn, timeOut, dateSubmitted, category, status, timestamp) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
for (Mantis mantis : list) {
preparedStatement.setInt(1, mantis.getTicketId());
preparedStatement.setString(2, mantis.getStartDate());
preparedStatement.setString(3, mantis.getEndDate());
preparedStatement.setInt(4, mantis.getHours());
preparedStatement.setInt(5, mantis.getMinutes());
preparedStatement.setInt(6, mantis.getEmployeeId());
preparedStatement.setString(7, mantis.getStartTime());
preparedStatement.setString(8, mantis.getEndTime());
preparedStatement.setString(9, mantis.getDateSubmitted());
preparedStatement.setString(10, mantis.getCategory());
preparedStatement.setString(11, mantis.getStatus());
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
preparedStatement.close();
} catch (SQLException e) {
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
}
I apprieciate the help :)
This seems more like it would be an integration test with the DB then a pure unit test. Also im not sure what it is that you want to test, if it is the query you will need to perform the insert and then try to get expected values from the DB and assert with expected result. Make sure that you use your own instance of the DB and also rollback after the test. DBUnit will make this happen for you, check it out
If you don't want to use any "mock" or "spy" classes (hand-made or from Mockito), you could consider a "cheap" database that lives in-memory (or backed by temporary files). Then your code can issue queries via JDBC just like the real thing, and your unit test can prepare data and inspect results (also via JDBC).
Be sure to read the answers for this similar question.

Categories