Improve the search functionality - java

How can I improve the search functionality.? I have written some codes to search for something.The search was taking too much time. And the code snippets here,
I am pulling the data from the database using this method.,
OracleConnection connection = null;
OraclePreparedStatement ptmst = null;
OracleResultSet rs = null;
OracleCallableStatement cstmt = null;
StringBuffer strBfr = new StringBuffer();
ArrayList myList = new ArrayList();
try
{
connection = (OracleConnection) TransactionScope.getConnection();
strBfr.append("select distinct .......... ");
ptmst = (OraclePreparedStatement)connection.prepareStatement(strBfr.toString());
rs = (OracleResultSet)ptmst.executeQuery();
while (rs.next())
{
HashMap hashItems = new HashMap();
hashItems.put("first",rs.getString(1));
hashItems.put("second",rs.getString(2));
myList.add(hashItems);
}
}
catch (Exception e) {
}
finally {
try {
if (ptmst != null) {
ptmst.close();
}
} catch (Exception e) {
}
try {
if (connection != null) {
TransactionScope.releaseConnection(connection);
}
} catch (Exception e) {
}
}
return myList;
In my jsp:
ArrayList getValues = new ArrayList();
getValues = //calling Method here.
for(int i=0; i < getValues.size();i++)
{
HashMap quoteSrch=(HashMap)allPOV.get(i);
first = (String)quoteSrch.get("first");
second = (String)quoteSrch.get("second");
}
Query:
SELECT DISTINCT(mtl.segment1),
mtl.description ,
mtl.inventory_item_id ,
mtl.attribute16
FROM mtl_system_items_b mtl,
mtl_system_items_tl k
WHERE 1 =1
AND mtl.organization_id = ?
AND k.inventory_item_id = mtl.inventory_item_id
AND NVL(orderable_on_web_flag,'N')= 'Y'
AND NVL(web_status,'UNPUBLISHED') = 'PUBLISHED'
AND mtl.SEGMENT1 LIKE ? --Here is the search term

Make sure organization_id , inventory_item_id and especially SEGMENT1 is indexed in your table.
Your query is pretty standard , if that doesn't work then it seems like your DB server is responding slow which could be due to number of reasons like low space , low memory , slow disk/read etc.
You can then ask your DBA/Server admins to check that.

First you need to find out the real problem
Is it the DB query
Is it the Network (is the App and the DB located on the same machine?)
Once you have identified that it is the DB query, then it becomes more of a DB question.
How does the two tables look like?
Any index used?
How does the data look like (How many rows etc)
After you have analyzed this, you should be able to post the question differently and expect an answer. I am not a DB guy, but I am sure someone would be able to provide some pointers.

Tunning has to be done:
Check TransactionScope.getConnection(); is giving connection without any delay.
Instead of creating new HashMap hashItems = new HashMap(); you can use
while (rs.next()){
myList.add(rs.getString(1) + "delimiter" + rs.getString(2));
}
in jsp use
first = allPOV.get(i).split("delimter")[0];
second = allPOV.get(i).split("delimter")[1];
so that you can reduce memory.
If possible use limit in your query, and use index on SEGMENT1 link.

Related

using JPA, method is taking a 60 sec

I am working with JPA, my web application is taking 60 sec to execute this method, I want to execute it faster how to achive ?
public boolean evaluateStudentTestPaper (long testPostID, long studentID, long howManyTimeWroteExam) {
Gson uday = new Gson();
Logger custLogger = Logger.getLogger("StudentDao.java");
// custLogger.info("evaluateTestPaper test paper for testPostID: " +
// testPostID);
long subjectID = 0;
// checking in table
EntityManagerFactory EMF = EntityManagerFactoryProvider.get();
EntityManager em = EMF.createEntityManager();
List<StudentExamResponse> studentExamResponses = null;
try {
studentExamResponses = em
.createQuery(
"SELECT o FROM StudentExamResponse o where o.studentId=:studentId And o.testPostID=:testPostID and o.howManyTimeWroteExam=:howManyTimeWroteExam")
.setParameter("studentId", studentID).setParameter("testPostID", testPostID)
.setParameter("howManyTimeWroteExam", howManyTimeWroteExam).getResultList();
System.out.println("studentExamResponses--------------------------------------------------"
+ uday.toJson(studentExamResponses) + "---------------------------------------");
} catch (Exception e) {
custLogger.info("exception at getting student details:" + e.toString());
studentExamResponses = null;
}
int studentExamResponseSize = studentExamResponses.size();
if (AppConstants.SHOWLOGS.equalsIgnoreCase("true")) {
custLogger.info("student questions list:" + studentExamResponseSize);
}
// Get all questions based on student id and test post id
List<ExamPaperRequest> examPaperRequestList = new ArrayList<ExamPaperRequest>();
List<Questions> questionsList = new ArrayList<Questions>();
// StudentExamResponse [] studentExamResponsesArgs =
// (StudentExamResponse[]) studentExamResponses.toArray();
// custLogger.info("Total questions to be evaluated: " +
// examPaperRequestList.size());
List<StudentTestResults> studentTestResultsList = new ArrayList<StudentTestResults>();
StudentTestResults studentTestResults = null;
StudentResults studentResults = null;
String subjectnames = "", subjectMarks = "";
int count = 0;
boolean lastIndex = false;
if (studentExamResponses != null && studentExamResponseSize > 0) {
// studentExamResponses.forEach(studentExamResponses->{
for (StudentExamResponse o : studentExamResponses.stream().parallel()) {
// 900 lines of coade inside which includes getting data from database Queries
}
}
As #Nikos Paraskevopoulos mentioned, it should probably be the ~900 * N database iterations inside that for loop.
I'd say to avoid DB iterations as much as you can, specially inside a loop like that.
You can try to elaborate your current StudentExamResponse sql to englobe more clauses - those you're using inside your for mainly, which could even diminish the amount of items you iterate upon.
My guess would be your select query is taking time.
If possible, set query timeout to less than 60 seconds & confirm this.
Ways of setting query timeout can be found out there - How to set the timeout period on a JPA EntityManager query
If this is because of query, then you may need to work to make select query optimal.

Java Setting Array values then loop through and set object field equal to array values

I have a pretty introductory question that I hope can get answered rather easily.
Currently I am trying to write something that queries my DB, returns result set (list of account id's) and then sets those account id's into an array so that I can populate an object with the values.
My object is going to be used as input into another method I have written but I can't figure out how I go about populating my account_id field on it with the values in my array that I returned in the result set. There doesn't seem to be any "setter" methods for lack of a better term on my array of type String.
I was able to get the array to populate with acct_id's from the result set and print them out so I know that I do have information coming back.
Below is the snippet I currently have, any help/improvements I could make would be greatly appreciated!
try {
connection = DriverManager.getConnection(url, user, password);
st = connection.createStatement();
rs = st.executeQuery(sql);
List<Long> array = new ArrayList<Long>();
while (rs.next()) {
array.add((long) rs.getLong("acct_id"));
for (Integer i = 0; i < array.size(); i++) {
System.out.println(array.get(i));
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = new AccountDTO(array[i]);
}
}
} catch (SQLException e) {
System.out.println("Connection failed.");
e.printStackTrace();
return;
}
if (rs.next()) {
System.out.println(rs.getString(1));
} else
System.out.print("Failed. Try again");
}
If my understanding is correct you may need the code below which is used to store all the account id's inside an array and you can use this to pass as a parameter to another method.
ArrayList<GetSummaryRequest> array1=new ArrayList<GetSummaryRequest>();
GetSummaryRequest request = new GetSummaryRequest();
while (rs.next())
{
request=new GetSummaryRequest();
request.accountKey=rs.getString("acct_id");
array1.add(request);
}
Now you have ArrayList of GetSummaryRequest with accountKey for each object.
if i understand correctly accountkey is integer right?
you can use Integer.parseint('your string!') class to convert the string to int.
i hope it helps
First of all , storing newline separated values in one column is not a good practice. This is against atomicity principle and will lead you to problems soon - ex., total number of accounts? how do you find it?
Once you convince yourself with this, you can use only one loop like this
List<GetSummaryRequest> summaryRequests = new ArrayList<GetSummaryRequest>();
while (rs.next()) {
String em = rs.getString("acct_id");
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = em;
summaryRequests.add(request);
}
return summaryRequests;
Probably you need something like that:
// First you get all ids
List<String> accountsIds = new ArrayList<String>();
while (rs.next()) {
accountsIds.add(rs.getString("acct_id"));
}
// Then iterate ids
for (String id : accountsIds) {
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = id;
}

how to add a check in Java code for fetching only non-negative values from result-set

In my Java code I have embedded a SQL query which fetches data from a database and stores it in a result-set. I want to add a function or a piece of code which will take only non-negative data from the result-set for further processing.
Assumption: The result set can contain positive/negative/zero data values as well as characters. Also i cannot change the SQL query as its out of my scope.
try something like this, i think it will do the job
private ArrayList getNegativeNumbers(ResultSet rs, String coulumnName ) throws SQLException
{
ArrayList ret = new ArrayList();
while(rs.next()){
try {
int x = rs.getInt(coulumnName);
if(x>=0){
ret.add(new Integer(x));
}
} catch (Exception ex) {
String x = rs.getString(coulumnName);
ret.add(x);
}
}
return ret;
}
UPDATED 2. Sorry for my edits, i missread the question
while (resultSet.next()) {
if(resultSet.getInt("Column name") > 0);
Processmethod(resultSet.getInt("Column name") );
}

Why does the NetBeans Java debugger never reach this code?

I'm trying to debug a method in Java using NetBeans.
That method is:
public Integer getNumberOfClamps(Locations paLocation) {
Integer ret = -1;
List list = new ArrayList();
String removeme = "ABC";
if (paLocation == null) {
return ret;
}
try {
IO io = new IO(this.getSchemaName());
Session session = io.getSession();
String sql = "select count(*) from assets a join assettypes at on (at.id = a.assettype_id) ";
sql += "where a.currentlocation_id = " + paLocation.getId() + " and at.clamp = 1 and at.active = 1;";
list = session.createQuery(sql).list();
// for some reason, list is empty yet MySQL reports 40 records
// and the following two lines are never reached!
ret = list.size();
removeme = "WHAT???";
} catch (Exception ex) {
ret = -1; // explicitly set return
} finally {
return ret;
}
}
Towards the middle of the method you will see list = session.createQuery(sql).list();
For some reason, this is returning an empty list even though when the SQL is run manually, I get 40 results.
But the odd part is that once the .list() is called, it jumps to the finally block and never reaches the rest! So for testing, 'removeme' should equal WHAT??? but the debugger reports it as still ABC.
What gives?
You are using the wrong method. 'createQuery' is expecting HQL syntax. Change your method to 'createSQLQuery'

how to increase the data transfer speed from oracle 10g into jsp pages using scriplet

I have incorporated my jsp pages with an autosuggest features, and to make the autosuggest functioning, it has to make an array of the data to be suggested using scriplet.
My issues is, as i import the data from oracle 10G, the time to complete the import of the data into the pages, is about 20-40 second.
Hence, is there any way to increase the speed of data transfer i already try the indexing method but it does help with the time, and the number of data in the table is about 6K .
Can the oracle pro, suggest any ways to solve this issues.. hehe =D
And here is the sample of my program :-
Function in my autosuggest.java, to retrieve and filter the data from my db.
public List getVendorName() throws Exception
{
List temp=null;
Database db=null;
String tempVar, tempVar2;
boolean tempVar3, tempVar4;
int counter=0;
try {
db = PersistenceHelper.beginTransaction();
JDOQuery queryFund = new JDOQuery(db,Trader.class);
queryFund.setFilter(PersistenceHelper.getOrganizationFilter("organization"));
temp = new ArrayList();
QueryResults results = queryFund.execute();
while(results.hasMore())
{
Trader trader = (Trader) results.next();
tempVar = "\""+trader.getName()+"\"";
tempVar2 = trader.getTraderType();
tempVar3 = trader.getRegTraderStatus();
tempVar4 = trader.getMainTraderStatus();
if(!tempVar2.equalsIgnoreCase("c"))
{
if( (tempVar3 == true) && (tempVar4 == true))
{
tempVar = tempVar.replace("\n", "");
temp.add(counter,tempVar); counter++;
}
}
}
}
catch (Exception e) {
System.out.println(e);
}
finally{
PersistenceHelper.closeTransaction(db, false);
}
return temp;
}
Function in my jsp page. to retrieve the data from autosuggest.java;
function getVendorName()
{
var temp = new Array();
<%
AutoSuggest as = new AutoSuggest();
List tempList = as.getVendorName();
for(int i=0; i<tempList.size(); i++)
{
Strinmg tempVar = (String) tempList.get(i);
%> temp[<%=i%>] = <%=tempVar%>; <%
}
%>
return temp;
}
The first thing to try would be to do the filtering by trader type and status in the database query ... rather on the Java side. The way you are currently doing this will entail pulling large numbers of Trader objects from the database. I expect most of them are then being discarded by your Java code.

Categories