Internal server error with SQL query - java

I am new to hibernate but I have a rough idea on what usually to do, this case, I can't say that is working out. I'm trying to create a filtering system which allows you to sort out different clients in this case with users. My SQL query is working correctly:
SELECT * FROM [de_user_site] WHERE [deactivation_time] = '9999-12-31 00:00:00.000' AND [user_id] IN (SELECT [user_id] FROM [de_users] WHERE [client_id] = 1)
And I've tried to turn that into a java query:
queryStr = "SELECT e FROM DeSiteUser e " + queryStr;
String queryStr = " WHERE e.deactivationTime = '9999-12-31 00:00:00.000' ";
if (clientId != null) {
queryStr += String.format("AND e.userId IN (SELECT id FROM DeUser u WHERE ");
if (clientId != null) {
queryStr += String.format("u.clientId = %d ", clientId);
}
}
However, I am having an issue with this:
Internal Server Error [#500]: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found 'null' near line 1, column 214 [SELECT e FROM com.velatt.dartentitlements.domain.DeSiteUser e WHERE e.deactivationTime = '9999-12-31 00:00:00.000' AND e.userId IN (SELECT id FROM com.velatt.dartentitlements.domain.DeUser u WHERE u.clientId = 6 ]
Does anyone know what I am forgetting, my SQL query is correct but I don't understand why it hasn't worked out for the java query?

You missed close braces. Error says it all.
SELECT e FROM com.velatt.dartentitlements.domain.DeSiteUser e WHERE e.deactivationTime = '9999-12-31 00:00:00.000' AND e.userId IN (SELECT id FROM com.velatt.dartentitlements.domain.DeUser u WHERE u.clientId = 6
Your code should have close braces something like this
queryStr = "SELECT e FROM DeSiteUser e " + queryStr;
String queryStr = " WHERE e.deactivationTime = '9999-12-31 00:00:00.000' ";
if (clientId != null) {
queryStr += String.format("AND e.userId IN (SELECT id FROM DeUser u WHERE ");
queryStr += String.format("u.clientId = %d ", clientId);
queryStr += " ) ";
}

Please replace your given code with below. you have missed to add ')' as the and of subquery.
queryStr = "SELECT e FROM DeSiteUser e " + queryStr;
String queryStr = " WHERE e.deactivationTime = '9999-12-31 00:00:00.000' ";
if (clientId != null) {
queryStr += String.format("AND e.userId IN (SELECT id FROM DeUser u WHERE ");
if (clientId != null) {
queryStr += String.format("u.clientId = %d )", clientId);
}
}

Related

JPA Query returns "No value specified for parameter 3" but all parameters are given

I am trying to create a Query to return a map with some IN clauses that only append to the query string when Set is not empty.
This is my method
public List<Object> findByFilter(String nome, DemandaStatus status, Set<Estado> estados, Set<Cidade> cidades, Set<Set<DemandaCategoria>> categorias, Set<Set<DemandaSubCategoria>> subCategorias) {
String sqlString = "SELECT new map(d.nmDemanda as nmDemanda, d.dsDemanda as dsDemanda, d.vlDemanda as vlDemanda) "
+ "FROM Demanda as d ";
sqlString = estados.isEmpty() ? sqlString : sqlString + "JOIN d.estado estados ";
sqlString = cidades.isEmpty() ? sqlString : sqlString + "JOIN d.cidade cidades ";
sqlString = categorias.isEmpty() ? sqlString : sqlString + "JOIN d.categorias categorias ";
sqlString = subCategorias.isEmpty() ? sqlString : sqlString + "JOIN d.subCategorias subs ";
sqlString = sqlString + "WHERE 1=1 ";
sqlString = nome == null ? sqlString : sqlString + "AND d.nmDemanda = :nome ";
sqlString = status == null ? sqlString : sqlString + "AND d.status = :status ";
sqlString = estados.isEmpty() ? sqlString : sqlString + "AND d.estado IN :estados ";
sqlString = cidades.isEmpty() ? sqlString : sqlString + "AND d.cidade IN :cidades ";
sqlString = categorias.isEmpty() ? sqlString : sqlString + "AND d.categorias IN :categorias ";
sqlString = subCategorias.isEmpty() ? sqlString : sqlString + "AND d.subCategorias IN :subs ";
Query query = em.createQuery(sqlString);
query = nome == null ? query : query.setParameter("nome", nome);
query = status == null ? query : query.setParameter("status", status);
query = estados.isEmpty() ? query : query.setParameter("estados", estados);
query = cidades.isEmpty() ? query : query.setParameter("cidades", cidades);
query = categorias.isEmpty() ? query : query.setParameter("categorias", categorias);
query = subCategorias.isEmpty() ? query : query.setParameter("subs", subCategorias);
return query.getResultList();
}
As I am trying with no "Estados" or "Cidades", this is the sqlString result
SELECT
new map(d.nmDemanda as nmDemanda, d.dsDemanda as dsDemanda, d.vlDemanda as vlDemanda)
FROM
Demanda as d JOIN d.categorias categorias JOIN d.subCategorias subs
WHERE 1 = 1
AND d.nmDemanda = :nome
AND d.status = :status
AND d.categorias IN :categorias
AND d.subCategorias IN :subs
And the query parameters are those 4, too.
This works fine (or seems to) and creates the Query as intended, as well as the Parameters, but I'm getting a "No value specified for parameter 3 (or other values here, when I pass more Sets in the parameter)".

antlr.NoViableAltException: unexpected token, WHERE clause, and unexpected token

I've already searched other problems related to this but I've just realized that maybe it's in the query of mine perhaps that this problem occurred or in the hibernate
SEE The where clause, it hasn't been called yet its there
what could be the problem?
Here is the whole code
try{
//one by one check the select field
String query = "Select emp.employeeID,emp.firstName,emp.middleName,emp.lastName,pos.positionName,dept.deptName,work.workplaceName"
+"from Employee emp "
+ "INNER JOIN Department dept "
+ "ON emp.departmentID = dept.deptID "
+ "INNER JOIN Position pos "
+ "ON emp.positionID = pos.positionID "
+ "INNER JOIN Workplace work "
+ "ON emp.workplaceID = work.workplaceID ";
if(checkAllNotEmpty(data)) {
query = query.concat("WHERE ");
if(data.getEmployeeID() != null && !data.getEmployeeID().equals("")) {
criteria.add(CRITERIA_EMPLOYEEID2);
System.out.println("Employee IDs");
input_empID = true;
}
if(data.getEmployeeName()!= null && !data.getEmployeeName().equals("")){
criteria.add(nameCriteriaHelper(data.getEmployeeName()));
System.out.println("Employee Name AKOOO");
input_empName = true;
}
if(data.getDepartmentID()!=0) {
criteria.add(CRITERIA_DEPARTMENT);
System.out.println("Dept ID ");
selected_dept = true;
}
if(data.getPositionID()!=0) {
criteria.add(CRITERIA_POSITION);
System.out.println("POS ID ");
selected_pos = true;
}
if(data.getWorkplaceID()!=0) {
criteria.add(CRITERIA_WORKPLACE);
selected_work = true;
}
query = query.concat(String.join(" OR ", criteria));
}
query = query.concat(" ORDER BY emp.joinDate DESC");
System.out.println("QUERY: " + query);
Query q = session.createQuery(query);
if(input_empID) {
q.setParameter("id", "%" + data.getEmployeeID() + "%");
}
if(input_empName) {
if(searchbyOne)
q.setParameter("inputName", "%" + data.getEmployeeName() + "%");
if(searchbyFandL)
q.setParameter("firstLastName", "%" +firstLastName+ "%");
if(searchbyCompName)
q.setParameter("completeName", "%" +completeName+ "%");
}
if(selected_dept) {
q.setParameter("deptID", data.getDepartmentID());
}
if(selected_pos) {
q.setParameter("posID", data.getPositionID());
}
if(selected_work) {
q.setParameter("workID", data.getWorkplaceID());
}
employees = (List<Object>) q.list();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
return employees;
}
So Help T.T

SPARQL query take a longer time in Eclipse compare to commande line

I need to compare SPARQL to SQL(Oracle based).
So I started with Jena and Eclipse. I created my RDF file and queries in SPARQL but when I execute a query in command line it took 5 secondes to get the result and with Eclipse it took 15 secondes !
The difference between the two computation times is huge and I can't compare properly these databases...
Is anyone know why ?
I save my RDF file in RDF/XML mode (by default).
Thanks !
There's the code i use :
String q = "SELECT ?appID ?appLibelle ?droit ?login ?password ?prenom ?nom "
+ "WHERE { "
+ "?empdroitapp EMPDROITAPP:EMP_ID ?emp . "
+ "?empdroitapp EMPDROITAPP:APP_ID ?app . "
+ "?empdroitapp EMPDROITAPP:EMPDroitAPP_Droit ?droit . "
+ "OPTIONAL { ?empapp EMPAPP:EMP_ID ?emp . "
+ "?empapp EMPAPP:APP_ID ?app . "
+ "?empapp EMPAPP:EMPAPP_Login ?login . "
+ "?empapp EMPAPP:EMPAPP_Password ?password . } . "
+ "?emp EMP:EMP_ID ?empID . "
+ "?emp EMP:EMP_Prenom ?prenom . "
+ "?emp EMP:EMP_Nom ?nom . "
+ "?app APP:APP_ID ?appID . "
+ "?app APP:APP_Libelle ?appLibelle . "
+ "} ORDER BY ASC(?empID)";
String prefix = "PREFIX LDAP: <http://example.com/property#>";
String prefixEMP = "PREFIX EMP: <http://example.com/property/emp#>";
String prefixAPP = "PREFIX APP: <http://example.com/property/app#>";
String prefixEMPAPP = "PREFIX EMPAPP: <http://example.com/property/empapp#>";
String prefixEMPDROITAPP = "PREFIX EMPDROITAPP: <http://example.com/property/empdroitapp#>";
String queryString = prefix + NL + prefixEMP + NL + prefixAPP + NL
+ prefixEMPAPP + NL + prefixEMPDROITAPP + q;
Query query = QueryFactory.create(queryString);
//query.serialize(new IndentedWriter(System.out, false));
QueryExecution qexec = QueryExecutionFactory.create(query, m);
long chrono = java.lang.System.currentTimeMillis();
try {
// Assumption: it's a SELECT query.
ResultSet rs = qexec.execSelect();
//String str = "appID\tappLibelle\tdroit\tlogin\tpassword\tprenom\tnom\n";
// The order of results is undefined.
for (; rs.hasNext();) {
QuerySolution rb = rs.nextSolution();
// Get title - variable names do not include the '?' (or '$')
RDFNode appID = rb.get("appID");
RDFNode appLibelle = rb.get("appLibelle");
RDFNode droit = rb.get("droit");
RDFNode login = rb.get("login");
RDFNode password = rb.get("password");
RDFNode prenom = rb.get("prenom");
RDFNode nom = rb.get("nom");
// Check the type of the result value
if (appID.isResource()) {
Resource res = (Resource) appID;
System.out.print("\t" + res);
} else {
System.out.print("\t" + appID);
}
if (appLibelle != null) {
System.out.print("\t" + appLibelle);
} else System.out.print("\tnull");
if (droit != null) {
System.out.print("\t" + droit);
} else System.out.print("\tnull");
if (login != null) {
System.out.print("\t" + login);
} else System.out.print("\tnull");
if (password != null) {
System.out.print("\t" + password);
} else System.out.print("\tnull");
if (prenom != null) {
System.out.print("\t" + prenom);
} else System.out.print("\tnull");
if (nom != null) {
System.out.print("\t" + nom);
} else System.out.print("\tnull");
System.out.println();
//str += "\n";
}
//System.out.println(str);
} finally {
// QueryExecution objects should be closed to free any system
// resources
qexec.close();
}
long tmp = java.lang.System.currentTimeMillis();
System.out.println("Temps écoulé : " + (tmp - chrono) + "ms");

PostgreSQL MAX aggregate function applied to strings and Java resultset

Hello and thank you for reading my post.
I have a PostgreSQL table "t" with a column "c" which type is "character varying(32)".
Values in this column look like this: "2014100605".
I am using the "MAX()" aggregate function to retrieve the maximum value in this column.
SELECT MAX(c) AS max FROM t;
In Java, if I prepare the query above, get a "resultSet" object and send it the getString("max") message, I get max = null.
If I send it the getInt("max") method instead, I get the result I'm expecting, something like "2014100605".
Is this normal behavior?
Am I really allowed to do this or is it by chance I'm getting the expected result?
Is "MAX()" actually using the lexicographical order?
Best regards.
A bit of Java code:
s_preparedSqlQuery =
"SELECT MAX(quotinv_nro) AS quotinv_nro_max "
+ "FROM imw_quotation_invoice "
+ "WHERE quotinv_type = ? "
+ "AND quotinv_nro LIKE '" + s_quotinvDate + "%'";
preparedStatement = m_connection.prepareStatement(s_preparedSqlQuery);
preparedStatement.setString(1, s_quotinvType);
resultSet = preparedStatement.executeQuery();
if(resultSet != null)
{
if(resultSet.next())
{
// s_quotinvNroMax = resultSet.getString("quotinv_nro_max");
n_quotinvNroMax = resultSet.getInt("quotinv_nro_max");
// if(s_quotinvNroMax == null)
if(n_quotinvNroMax == 0)
{
n_nbQuotinvsThisSameDate = 0;
return n_nbQuotinvsThisSameDate;
}
else
{
s_quotinvNroMax = Integer.toString(n_quotinvNroMax);
n_length = s_quotinvDate.length();
s_currentMaxNro = s_quotinvNroMax.substring(n_length - 1);
n_nbQuotinvsThisSameDate = Integer.valueOf(s_currentMaxNro);
}
}
}
If you are hitting on a unique Id column....
int maxID = 0;
Statement s2 = con.createStatement();
s2.execute("SELECT MAX(UniqueId) FROM MyTable");
ResultSet rs2 = s2.getResultSet();
if (rs2.next())
{
maxID = rs2.getInt(1);
}
If you are hitting on any other non-key column....
int maxID = 0;
Statement s2 = con.createStatement();
s2.execute("SELECT MAX(ColumnValue) FROM MyTable");
ResultSet rs2 = s2.getResultSet();
while (rs2.next())
{
maxID = rs2.getInt(1);
}

set parameter which is null in #NamedQuery (JPA QL 1.0)

I am writing a JPA QL named query that would search for documents. This should be done in only one query and I cannot switch to native SQL (that's non functional requirement).
The query I wrote looks as follows:
query = "select doc from Doc doc " +
" join doc.Csts cst " +
" where cst.cstFrstNm like :FrstNm " +
" and cst.cstLastNm like :LastNm " +
" and doc.resId = :id ";
This query is parametrized using following instructions:
query.setParameter("FrstNm ", firstName + '%');
query.setParameter("LastNm ", lastName + '%');
query.setParameter("id", resId);
firstName, lastName, resId in the above code are my search criteria and they are all Strings and they can be null. When one of them is null, it shouldn't be taken into consideration when the query is invoked.
For instance:
Let's say that: firstName = "John", lastName = "Doe" and resId is null, then the query should return all the entries from Doc table that are for user John Doe, no matter what is their resId.
I was trying to put additional OR and AND conditions into query that'd check if resId is null but it didn't work. I'm testing it on HSQLDB.
Is it any way to modify this JPA query to handle null values?
Two solutions:
First one, don't use a named query and craft a new query for each request:
boolean first = true;
query = query = "select doc from Doc doc " +
" join doc.Csts cst " +
if (firstName != null) {
query += (first ? " where " : " and ");
query += " cst.cstFrstNm like :FrstNm ";
first = false;
}
query += ";";
// ...
Second solution, you are using wildcard. If your parameter is empty, just put a '%' in your query, which will match all corresponding strings:
query.setParameter("FrstNm ", (firstName != null ? firstName : "") + '%');
query.setParameter("LastNm ", (lastName != null ? lastName : "") + '%');
If firstName is empty, your query will look like:
... cst.cstFrstNm like '%' ...
and will match all the values. It will result in the parameter not filtering any result, with a behaviour similar as if it wasn't present.
You may need to build the query dynamically to satisfy your parameters. For instance:
public List<Employee> findEmployees(String name, String deptName, String projectName, String city) {
StringBuffer query = new StringBuffer();
query.append("SELECT DISTINCT e ");
query.append("FROM Employee e LEFT JOIN e.projects p ");
query.append("WHERE ");
List<String> criteria = new ArrayList<String>();
if (name != null) { criteria.add("e.name = :name"); }
if (deptName != null) { criteria.add("e.dept.name = :dept"); }
if (projectName != null) { criteria.add("p.name = :project"); }
if (city != null) { criteria.add("e.address.city = :city"); }
if (criteria.size() == 0) {
throw new RuntimeException("no criteria");
}
for (int i = 0; i < criteria.size(); i++) {
if (i > 0) { query.append(" AND "); }
query.append(criteria.get(i));
}
Query q = em.createQuery(query.toString());
if (name != null) { q.setParameter("name", name); }
if (deptName != null) { q.setParameter("dept", deptName); }
if (projectName != null) { q.setParameter("project", projectName); }
if (city != null) { q.setParameter("city", city); }
return (List<Employee>)q.getResultList();
}
You migt also like to consider Criteria API if you are using JPA 2.0 for this kind of task.

Categories