Flexiblesearch error: missing values - mysql

Hybris Console :
ERROR [hybrisHTTP19] [FlexibleSearch] Flexiblesearch error: missing values for [emailId, productCode], got {13=8796135981138, issent=false, productcode =0100, emailid ='hybrisa#gmail.com'}
ERROR [hybrisHTTP19] [FlexibleSearch] query was 'SELECT {p:pk} FROM {NotifyStock AS p} WHERE {p:status}=?isSent AND {p:productId}=?productCode AND {p:emailId}=?emailId '
ERROR [hybrisHTTP19] [FlexibleSearch] translated query was: SELECT item_t0.PK FROM notifystock item_t0 WHERE ( item_t0.p_status =? AND item_t0.p_productid =? AND item_t0.p_emailid =?) AND (item_t0.TypePkString=? )
Aug 31, 2015 6:51:35 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [DispatcherServlet] in context with path [/store] threw exception [Request processing failed; nested exception is de.hybris.platform.servicelayer.search.exceptions.FlexibleSearchException: missing values for [emailId, productCode], got {13=8796135981138, issent=false, productcode =0100, emailid ='hybrisa#gmail.com'}] with root cause
de.hybris.platform.jalo.flexiblesearch.FlexibleSearchException: missing values for [emailId, productCode], got {13=8796135981138, issent=false, productcode =0100, emailid ='hybrisa#gmail.com'}[HY-0]
at de.hybris.platform.persistence.flexiblesearch.TranslatedQuery.removeUnusedValues(TranslatedQuery.java:274)
at de.hybris.platform.jalo.flexiblesearch.FlexibleSearch.search(FlexibleSearch.java:1423)
at de.hybris.platform.jalo.flexiblesearch.FlexibleSearch.search(FlexibleSearch.java:1627)
at de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService$2.execute(DefaultFlexibleSearchService.java:374)
at de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService$2.execute(DefaultFlexibleSearchService.java:1)
at de.hybris.platform.servicelayer.session.impl.DefaultSessionService.executeInLocalView(DefaultSessionService.java:88)
at de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService.getJaloResult(DefaultFlexibleSearchService.java:363)
at de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService.search(DefaultFlexibleSearchService.java:164)
at de.hybris.merchandise.core.notifystock.NotifyStockServices.isAlreadyExists(NotifyStockServices.java:118)
at de.hybris.merchandise.facades.NotifyStock.impl.NotifyStockFacadeImpl.isAlreadyExists(NotifyStockFacadeImpl.java:51)
at de.hybris.merchandise.storefront.controllers.misc.AddToCartController.verifyEmail(AddToCartController.java:132)
Working Query in HAC :
select {p:PK} From {NotifyStock AS p} WHERE {p:status}=0 AND {p:productId}=0100 AND {p:emailId}='ertsergt#gmail.com'
Flexiblesearch Query(Not working):
final StringBuilder builder = new StringBuilder();
builder.append("SELECT {p:").append(ItemModel.PK).append("} ");
builder.append("FROM {").append(NotifyStockModel._TYPECODE).append(" AS p} ");
builder.append("WHERE ").append("{p:").append(NotifyStockModel.STATUS).append("}").append("=?isSent ");
builder.append("AND ").append("{p:").append(NotifyStockModel.PRODUCTID).append("}").append("=?productCode ");
builder.append("AND ").append("{p:").append(NotifyStockModel.EMAILID).append("}").append("=?emailId ");
final String email = "\'" + notifyStockModel.getEmailId() + "\'";
final FlexibleSearchQuery query = new FlexibleSearchQuery(builder.toString());
query.setNeedTotal(true);
query.addQueryParameter("isSent", Boolean.FALSE);
query.addQueryParameter("productCode ", notifyStockModel.getProductId());
query.addQueryParameter("emailId ", email);
When i Fire the above Query in HAC the query is working fine but when i fired the same query using flexible search i am getting some flexiblesarch exception.Can anyone tell me what is the Mistake in my flexible search query?Any help would be appreciated?

Adding to what Shresht has answered, always make it a habit to use the field name constants in the parameter map as well.
Example :
query.addQueryParameter(NotifyStockModel.PRODUCTID, notifyStockModel.getProductId());
query.addQueryParameter(NotifyStockModel.EMAILID, email);
The above syntax will never lead to issues. Also for such direct matching queries, I suggest you use flexible search's below method :
flexibleSearchService.getModelByExample(example)
This results in a more maintainable code. Check the wiki for more info.

I think you are giving extra space while adding query parameter for productCode and emailId in FlexibleSearchQuery. That's why you are getting missing values for [emailId, productCode] error.
Replace this
query.addQueryParameter("productCode ", notifyStockModel.getProductId()); // extra space after productCode
query.addQueryParameter("emailId ", email); // extra space after emailId
with
query.addQueryParameter("productCode", notifyStockModel.getProductId());
query.addQueryParameter("emailId", email);
Hope this will fix your problem.

Related

JPQL 'Function' doesn't send operator

I am using EclipseLink over Spring Boot and have this jpql in a repository:
#Query("select function('pMonth',p.payDay) ,sum(p.price) " +
"from FullPayment p where " +
"group by function('pMonth', p.payDay)"
)
List<Object[]> paymentMonthlyHistory();
but it does not send the operator p.payDay calling my custom function pMonth. Here is the database error:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for FUNCTION adventure_db.pMonth; expected 1, got 0
Error Code: 1318
Call: SELECT pMonth(), SUM(PRICE) FROM panel_fullPayment WHERE ((PAYDATE >= ?) AND (TRANSACTIONAMOUNT >= PRICE)) GROUP BY pMonth()
bind => [1 parameter bound]
I use Mysql as DBMS. Any help would be appreciated
The problem was a typo. The field name is payDate but I wrote p.payDay. I put the answer here to emphasize that if you mistype the field name here, it won't show you an error on boot, but will generate a wrong query.

if null return blank in spring data jpa Query

I have the below #Query in my repository
#Query("select new Foo(id, code, coalesce(properties, '') as properties, env) "
+ "from Foo order by id desc")
public List<Foo> findAll();
I want to return blank for properties when its null.
But when I run the service I am getting below error:
unexpected token: as near line 1, column 87
Any idea on how to resolve this error? Thanks in advance.
The error is coming from trying to declaring an alias in a constructor expression. Remove the as properties.

How to use Oracle's JSON_VALUE function with a PreparedStatement

I am trying to run a SQL query using Oracle's json_value() function using a PreparedStatement.
Assume the following table setup:
drop table foo cascade constraints purge;
create table foo
(
id integer primary key,
payload clob,
constraint ensure_json check (payload IS JSON STRICT)
);
insert into foo values (1, '{"data": {"k1": 1, "k2": "foo"}}');
The following SQL query works fine:
select *
from foo
where json_value(payload, '$.data.k1') = '1'
and returns the expected row.
However, when I try to run this query using a PreparedStatement like in the the following piece of code:
String sql =
"select *\n" +
"from foo\n" +
"where json_value(payload, ?) = ?";
PreparedStatement pstmt = conection.prepareStatement(sql);
pstmt.setString(1, "$.data.k1");
pstmt.setString(2, "1");
ResultSet rs = pstmt.executeQuery();
(I removed all error checking from the example to keep it simple)
This results in:
java.sql.SQLException: ORA-40454: path expression not a literal
The culprit is passing the json path value (parameter index 1), the second parameter is no problem.
When I replace (only) the first parameter with a String constant json_value(payload, '$.data.k1') = ? the prepared statement works fine.
In a desperate attempt, I also tried including the single quotes in the parameter: pstmt.setString(1, "'$.data.k1'") but not surprisingly, Oracle wouldn't accept it either (same error message).
I also tried using json_value(payload, concat('$.', ?) ) and only passing "data.k1" as the parameter - same result.
So, the question is:
How can I pass a JSON path expression to Oracle's json_value function using a PreparedStatement parameter?
Any ideas? Is this a bug in the driver or in Oracle? (I couldn't find anything on My Oracle Support)
Or is this simply a case of "not implemented"?
Environment:
I am using Oracle 18.0
I tried the 18.3 and 19.3 version of the ojdbc10.jar driver together with OpenJDK 11.
It isn't the driver - you get the same thing with dynamic SQL:
declare
result foo%rowtype;
begin
execute immediate 'select *
from foo
where json_value(payload, :1) = :2'
into result using '$.data.k1', '1';
dbms_output.put_line(result.payload);
end;
/
ORA-40454: path expression not a literal
ORA-06512: at line 4
And it isn't really a bug, it's documented (emphasis added):
JSON_basic_path_expression
Use this clause to specify a SQL/JSON path expression. The function uses the path expression to evaluate expr and find a scalar JSON value that matches, or satisfies, the path expression. The path expression must be a text literal. See Oracle Database JSON Developer's Guide for the full semantics of JSON_basic_path_expression.
So you would have to embed the path literal, rather than bind it, unfortunately:
declare
result foo%rowtype;
begin
execute immediate 'select *
from foo
where json_value(payload, ''' || '$.data.k1' || ''') = :1'
into result using '1';
dbms_output.put_line(result.payload);
end;
/
1 rows affected
dbms_output:
{"data": {"k1": 1, "k2": "foo"}}
or for your JDBC example (keeping the path as a separate string as you presumably want that to be a variable really):
String sql =
"select *\n" +
"from foo\n" +
"where json_value(payload, '" + "$.data.k1" + "') = ?";
PreparedStatement pstmt = conection.prepareStatement(sql);
pstmt.setString(1, "1");
ResultSet rs = pstmt.executeQuery();
Which obviously isn't what you want to do*, but there doesn't seem to be an alternative. Other than turning your query into a function and passing the path variable in to that, but then the function would have to use dynamic SQL, so the effect is much the same - maybe easier to handle SQL injection concerns that way though.
* and I'm aware you know how to do this the embedded way, and know you want to use bind variables because that's the correct thing to do; I've spelled it out more than you need for other visitors *8-)

Insert query failing when using a parameter in the associated select statement in SQL Server CE

INSERT INTO voucher (voucher_no, account, party_name, rece_amt, particulars, voucher_date, voucher_type, cuid, cdt)
SELECT voucher_rec_no, #account, #party_name, #rece_amt, #particulars, #voucher_date, #voucher_type, #cuid, #cdt
FROM auto_number
WHERE (auto_no = 1)
Error:
A parameter is not allowed in this location. Ensure that the '#' sign is in a valid location or that parameters are valid at all in this SQL statement.
I've just stumbled upon this whilst trying to fix the same issue. I know it's late but, assuming that you're getting this error when attempting to execute the query via .net, ensure that you are setting the SqlCeParameter.DbType - if this is not specified, you get the exception you listed above.
Example (assume cmd is a SqlCeCommand - all the stuff is in the System.Data.SqlServerCe namespace):
SqlCeParameter param = new SqlCeParameter();
param.ParameterName = "#SomeParameterName";
param.Direction = ParameterDirection.Input;
param.DbType = DbType.String; // this is the important bit to avoid the exception
param.Value = kvp.Value;
cmd.Parameters.Add(param);
Obviously, you'd want to set the DB type to match the type of your parameter.

simple sql query gone wrong

I am trying to make a sql query and input that into a variable called tid. This is using the ruby on rails language where I am trying to attempt with the bottom code.
#test = Customer.where(:email => #email).first tid = #test[:id]
Moreover, it gives me a 500 Internal Error saying "Action Controller: Exception caught"
Thank you in advance
Your #test should be a Customer object or nil, not a Hash. You should try:
tid = #test.try(:id)
That will give you the Customer ID or nil in tid.