jcr query construct - java

I am building a jcr query and receive data from repository. Here is my code:
String queryString = "SELECT * FROM public:hours";
try {
// get session
Session session = requestContext.getSession();
// create query from queryString constructed
Query q = session.getWorkspace().getQueryManager().createQuery(queryString, Query.JCR_SQL2);
// execute query and retrieve result
QueryResult result = q.execute();
// debug line
log.error("query is", q.getStatement());
....
But this can not execute successfully. It gives me an error that
Repositorty Failed:
[INFO] [talledLocalContainer] javax.jcr.query.InvalidQueryException: Query:
[INFO] [talledLocalContainer] SELECT * FROM public:(*)hours; expected: <end>
In the jcr-shell, it works if I type in query sql "select * from public:hours" and will give me proper results.
I searched many references but almost every example is the same as mine. so I am not sure where the problem is.
Anyone have experience with this please help.

If you're using the JCR-SQL2 query language, then you should quote the selector name with square brackets:
SELECT * FROM [public:hours]
For details, see Section 6.7.4 of the JSR-283 (aka, JCR 2.0) specification, which is also available online. Note that the square bracket quote characters are not required if the name were to be a valid SQL92 identifier. The node type names containing namespace prefixes always need to be quoted, since the ':' character is not allowed in SQL92 identifiers.
Of course, this assumes that you have a node type named "public:hours", where "public" is the namespace prefix.

Related

Can we modify the query using Statement Inspector after binding the parameters to query

Getting the query in Statement Inspector after the parameters are binded.
I am following the below links for statement inspector, can the query be modified after the parameters are binded.
https://vladmihalcea.com/hibernate-statementinspector/
https://stackoverflow.com/questions/39112308/how-i-can-configure-statementinspector-in-hibernate
For eg:
Query q = entityManager.createNativeQuery("Select * from employees where address2_id = ?");
q.setParameter(1, address2_idval);
For the above scenario if i log the query using inspector it's printing
Select * from employees where address2_id = ?
the reason i am using inspector is sometimes address2_idval can be empty(very rare case) at that time it's generating Select * from employees where address2_id = '' where address2_id is a numeric datatype in Db(POSTGRES).
I am getting the following error invalid input syntax for type numeric "".
What i am planning on implementing in inspector is if i can get Select * from employees where address2_id = '' like this in inspector block i can check with regex and replace = '' with is null.
Can anyone pls suggest if this is possible?
NOTE: We are migrating from oracle to potgres so there are tons of queries which might face this issue, so planning on implementing in one place which intercept all the queries with this scenario

sparql using live.dbpedia and getting XML Schema in the result

I'm adventuring with sparql and a java application, I've found a few connection basics to get up and running as it were but fear I'm making a mistake which will later turn into something worse.
Every connection suggestion regardless of the library used says to connect to "http://dbpedia.org/sparql/" yet this doesn't work for me.
I checked the url that is returned when I run a query using the online editor and noticed the live prefix, so I added that as my connection string, and it works. That is to say, my connection string looks like "http://live.dbpedia.org/sparql"
And it does return the result, however, the result has the XML Schema attached which is making me wonder whether or not it's because of this live. I've added in.
Below is the simple connection code I'm using, is this correct? Any and all help greatly appreciated thank you.
If the 'live' is correct, is it possible to extra the just the value wihtout the Schema?
StringBuilder sb = new StringBuilder();
sb.append("PREFIX dbr: <http://dbpedia.org/resource/> \n");
sb.append("PREFIX dbp: <http://dbpedia.org/property/> \n");
sb.append("PREFIX dbo: <http://dbpedia.org/ontology/> \n");
sb.append("SELECT ?dob \n");
sb.append("WHERE {dbr:Tony_Blair dbp:birthDate ?dob} \n");
Query query = QueryFactory.create(sb.toString());
QueryExecution qexec = QueryExecutionFactory.sparqlService("http://live.dbpedia.org/sparql", query);
try {
ResultSet results = qexec.execSelect();
for ( ; results.hasNext() ; )
{
QuerySolution soln = results.nextSolution() ;
System.out.println(soln.get("?dob"));
}
the result being:
1953-05-06^^http://www.w3.org/2001/XMLSchema#date
Well the result as you show it is missing some brackets and quotes, but I assume that is caused by how you copy-pasted it. More usually it would look like this:
"1953-05-06"^^<http://www.w3.org/2001/XMLSchema#date>
But in essence your query and code is correct. The "attached XML Schema" here is the datatype of the returned literal string.
An RDF literal consists of a lexical value (in your case "1953-05-06") and a datatype (in your case http://www.w3.org/2001/XMLSchema#date). It can also, optionally have a language tag e.g. "colour"#en-UK.
If you wish to remove the datatype from the result and only retrieve the lexical value, you can use the STR() function as part of the SELECT clause in your query:
SELECT (STR(?dob) as ?date_of_birth)
As for the connection string that you are struggling with: there are two separate DBPedia endpoints. The "regular" one is http://dbpedia.org/sparql (no trailing slash) - this queries a static dataset that is synced/updated with Wikipedia changes every so 6 months or so. The "live" endpoint, http://live.dbpedia.org/sparql, is an effort to have a more up-to-date dataset ready for querying. See https://wiki.dbpedia.org/online-access/DBpediaLive for more details.

jpql left join fetch not returning results for like

In a spring mvc app using hibernate and MySQL, I have written the following query method to return a list of names with patients:
#SuppressWarnings("unchecked")
public Collection<Person> findPersonByLastName(String ln) throws DataAccessException{
Query query = this.em.createQuery("SELECT DISTINCT pers FROM rimPerson pers left join fetch pers.names nm WHERE nm.family LIKE :lnm");
query.setParameter("lnm", ln);
return query.getResultList();
}
This is producing the following hibernate sql:
Hibernate:
select distinct
person0_.hppid as hppid1_340_0_,
names1_.HJID as HJID1_89_1_,
person0_2_.classCode_HJID as classCod2_339_0_,
person0_1_.administrativeGenderCode_HJID as administ2_341_0_,
person0_1_.birthTime_HJID as birthTim3_341_0_,
names1_.DELIMITER_ as DELIMITE2_89_1_,
names1_.FAMILY as FAMILY3_89_1_,
names1_.named_entity_hppid as named5_89_1_,
names1_.SUFFIX as SUFFIX4_89_1_,
names1_.name_entity_HJID as name9_340_0__,
names1_.HJID as HJID1_89_0__
from
rim_person person0_ inner join rim_living_subject person0_1_ on person0_.hppid=person0_1_.hppid
inner join rim_entity person0_2_ on person0_.hppid=person0_2_.hppid
inner join rim_infrastructure_root person0_3_ on person0_.hppid=person0_3_.hppid
left outer join EN names1_ on person0_.hppid=names1_.name_entity_HJID
where names1_.FAMILY like ?
When I call the above jpql method with the following command, it returns zero results:
this.myappService.findPersonByLastName("");
I also get zero results when I cut and past the above generated hibernate code into the MySQL command line client and replace ? with ''.
If, however, I remove the where names1_.FAMILY like ? from the hibernate generated sql above and place the shortened sql into the MySQL command line client, I get four results, eachof which has a value for the lastname field.
How can I change the jpql so that it generates a hibernate query that returns the four results when `` is passed as the empty string parameter? I want the result set to include every result when the user gives empty input, but to give filtered results when the user types in any given text input.
The typical reason that like fails to do what you think it ought to do is to forget to put a wildcard in the pattern string. For example, if you want to match all user names that begin with 'Code' you must do something like name like 'Code%', NOT name like 'Code'. You can control exactly what your predicate matches with careful placement of %s in your string.
Try this to see all entities no matter what the value in family:
this.myappService.findPersonByLastName("%");
It is kinda cheesy to have the caller of findPersionByLastName have to put in the % wildcard. A better implementation is to have the caller specify which last name they are looking for, and then have the code that constructs the query put the wildcard in the right place. When you are looking for last names, you might do something like this:
query.setParameter("lnm", "%" + ln);
That would match anything that ends with the parameter that is passed to the method.

SQL Firebird implementation in java/ IBSQL

so tried to put that SQL code into my java-aplication:
SELECT DISTINCT
StRzImRo.Rohstoff, StRo.Bezeichnung,
CAST (SUM(BwLsImAt.Lieferungen * StRzImRo.Menge * StAt.PROD__REZEPTURGEWICHT / Coalesce(StRz.PARM__BEZUGSGROESSE,1)) AS NUMERIC (9,3)) Rohstoffverbrauch_Gesamt FROM BwLsImAt
JOIN StAt ON (StAt.IntRowId = BwLsImAt.Artikel)
JOIN StRz ON (StRz.IntRowId = StAt.PROD__REZEPTUR)
JOIN StRzImRo ON (StRzImRo.Master = StRz.IntRowId)
JOIN StRo ON (StRzImRo.Rohstoff = StRo.IntRowId)
WHERE StAt.IntRowId > 0
GROUP BY StRzImRo.Rohstoff, StRo.Bezeichnung
-- GROUP BY StRzImRo.Rohstoff, StRzImRo.Menge, StAt.PROD__REZEPTURGEWICHT, Coalesce(StRz.PARM__BEZUGSGROESSE,1)
The code is fully funcional and tested in IBSQL but not working in my java-application.
My app does work properly with other code. I get this error:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 266
ON
I would be very happy if someone could help me with this problem. Thanks!
P.S.: Sorry for my bad language, but i´m not a native speaker
The error suggests there is an ON in an unexpected place in your query, and as the query itself looks fine, my guess is the problem is with the way you construct the query in your Java application. There might be some whitespace missing in your query.
My guess is that you have something like
query = "SELECT * " +
"FROM table1" +
"JOIN table2 ON " //.....
The missing whitespace will make the SQL:
SELECT * FROM table1JOIN table2 ON ....
For the parser, this is perfectly valid until it encounters the ON token, which triggers the error. Eg the parser identifies it is a SELECT with * (all) columns from table1JOIN with alias table2. During parsing the server doesn't check if the table actually exists, so it doesn't trip over the fact that table1JOIN doesn't exist. That is checked after parsing is successfully completed.

How to Manipulate SQL specified in jrxml template

Problem: Report Templates are created by Admin Users who only decide what data to show where as the filter for the data is specified by the business user. In simpler SQL terms, query is specified by the Admin User, Business User specifies the WHERE clause.
Jasper allows user to specify parameters in SQL query like $P{city}. I have tried to retrieve the query dynamically using the method specfied in the link.
Possible Solution can be
Use WHERE clause parameters in JRXML and replace them while report creation - This will save me SQL parsing but I don't want to guide the admin user with this complexity. Parsing is not a huge problem.
Use my custom jdbc query executor and factory, only created to allow me extension point before jasper fire SQL query. I will be completely relying on vanilla Jasper JDBC data source but will only modify query before execution. JRAbstractQueryExecuter simplifies the query and replace the jasper related tokens before firing query - This will be very dirty and will force me to be implementation specific.
Do the same replacement as it is done in JRAbstractQueryExecuter in my application code base, parse the SQL query, modify it and set it again as specified in link
Can you please suggest a better way of doing this? I have a feeling that this can definitly be done in cleaner way.
Thanks for your help
You could create an input control to determine the desired WHERE clause and use a parameter to hold the contents of that WHERE clause. The default value expression would be something like:
$P{theParameter} == "value_1" ?
(" AND CONDITION_1 IN ('A', 'B', 'C') AND CONDITION_2 = 'Yes' "
) : " AND CONDITION_3 = 'Other' AND CONDITION_4 = 'No' "
Then in your WHERE clause you would reference it like:
WHERE
.... = .....
AND .... = ....
AND .... = ....
$P!{theParameter}
If your constraint columns are the same across your WHERE clauses, you could use $P! to bring in the parameter value literally, and reference it in your query:
WHERE
.... = .....
AND .... = ....
AND .... = ....
AND thisValue = $P!{theParameter}

Categories