I'm having some trouble to create a query where a necessary condition is to use a like into a field where I need to replace a special character. Something like this:
public List<MyClass> search(Myclass object){
Criteria cri = criteria(MyClass.class);
if(object.getName() != null){
cri.add(Restrictions.sqlRestriction("replace("+cri.getAlias()+".name,"+object.getSpecialCharacter()+", '') like '"+object.getName()+"'"));
}
if(dominio.getType()!= null){
cri.add(Restrictions.eq("type", object.getType()));
}
if(dominio.getWorkspace() != null){
cri.add(Restrictions.eq("workspace", object.getWorkspace()));
}
if(dominio.getStatus() != null){
cri.add(Restrictions.eq("status", object.getStatus()));
}
return cri.list();
}
With this code I've got the error below:
this_.ID_MYCLASS as ID_MYCLASS1_33_0_,
this_.NM_MYCLASS as NM_MYCLASS4_33_0_,
this_.ID_STATUS as ID_STATU5_33_0_,
this_.ID_TYPE as ID_TYPE_7_33_0_,
this_.ID_WORKSPACE as ID_WORKS8_33_0_
from KDTB_MYCLASS this_
where replace(this.name,'_', '') like 'COD'
and this_.ID_WORKSPACE=?
ORA-00904: "THIS"."NAME": invalid identifier
What am I doing wrong?
Thanks in advance!
Try this instead:
cri.add(Restrictions.sqlRestriction("replace({alias}.name,"+object.getSpecialCharacter()+", '') like '"+object.getName()+"'"));
You could try this as the first parameter of sqlRestriction:
"replace("+cri.getAlias()+"_.name,"
Ultimately, you're pointing out that HQL doesn't support the replace routine. If you have more trouble, consider ditching Criteria & use a native SQL query for this.
Related
I want to simulate this query using kotlin exposed framework:
SELECT max(episodes.season_number) FROM episodes WHERE episodes.parent_id = 944947
I tried the next one query:
fun countSeasonsForParentId(id: Int) = transaction {
EpisodeTable.slice(EpisodeTable.season)
.select { EpisodeTable.parentId eq id }
.map { it[EpisodeTable.season] }.maxOrNull()
}
But this query just results in:
SELECT episodes.season_number FROM episodes WHERE episodes.parent_id = 944947
and the max value is selected in the code.
How to perform finding max value on the side of the database and map it to Int?
I tried similar query and I believe it fits your need.
The query is:
Reservations
.slice(Reservations.date.max())
.select { Reservations.note eq "it" }
.maxByOrNull { Reservations.date }
And it generates SQL query:
SELECT MAX(reservations."date") FROM reservations WHERE reservations.note = 'it'
Your query can be used as:
EpisodeTable
.slice(EpisodeTable.season.max())
.select { EpisodeTable.parentId eq id }
.maxByOrNull { EpisodeTable.season }
?.get(EpisodeTable.season.max())
Alternative, for extracting one value seems more appropriate:
EpisodeTable
.slice(EpisodeTable.season.max())
.select { EpisodeTable.parentId eq id }
.firstOrNull()
?.get(EpisodeTable.season.max())
I need to pass in a variable number of parameters to a spring/JPA repo to mimick something like this.
select * from myTable
where name like '%SOME_VALUE%'
or name like '%SOME_OTHER_VALUE%'
or name like '%SOME_OTHER_VALUE2%'
or an unknown number of other values
So far I haven't been able to determine what the correct way to to do this is. I'm using Spring 4.3.7, Hibernate 5.2.9, and Spring Data 1.11.1. I've googled around and it doesn't appear that there's way to do this with a normal CRUD repo, but so far I haven't found any examples that look like what I need. I think CriteriaBuilder is what I am supposed to use, but that seems to have fallen out of favor, so I'm not sure what the correct way to do this is.
So I followed #Jorge Campos advice and used specification. My code looks like this now:
public Stream<Product> findProductsContainingDesc(Collection<String> withDesc) {
Specifications<Product> specifications = null;
for (String s : withDesc) {
if(specifications == null){
specifications = where(hasDescriptionLike(s));
}else{
specifications = specifications.or(hasDescriptionLike(s));
}
}
return internalProductRepository.findAll(specifications).stream();
}
public static Specification<Product> hasDescriptionLike(String desc) {
return (root, query, builder) -> builder.like(root.get("description"), "%" + desc + "%");
}
And my repo definition is this.
interface InternalProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor
Perhaps you are looking for something like this?:
#Query("select e from Entity e "
+"where (:field1 = '' or e.field1 like '%:field1%') "
+"and (:field2 = '' or e.field2 like '%:field2%') "
//...
+"and (:fieldN = '' or e.fieldN like '%:fieldN%')"
Page<Entity> advancedSearch(#Param("field1") String field1,
#Param("field2") String field2,
//...
#Param("fieldN") String fieldN,
Pageable page);
Source.
I would like to update only fields that had been updated (they wont be null).
I would like to create a dynamic set, for example (not a valid code):
dslContext.update(table)
if(field1 != null) {
.set(field1, val1)
}
if(field2 != null) {
.set(field2, val2)
}
.where(condition1)
.and(condition2)
.execute();
Is there a way to do this?
While you could certainly achieve this by (ab)using the DSL API, the best way to actually do this is by using one of the following methods:
UpdateSetStep.set(Map)
UpdateSetStep.set(Record)
An example using Record:
Record record = dslContext.newRecord(table);
if (field1 != null)
record.set(field1, val1)
if (field2 != null) {
record.set(field2, val2)
dslContext.update(table)
.set(record)
.where(condition1)
.and(condition2)
.execute();
We are trying to query Salesforce with an ArrayList in the where statement.
Below is is the error we ran into when we tried using the ArrayList in the where clause.
Query we used against Salesforce:
Select Id,Billing_Number__c from Call_Log__c where Id in #[flowVars.successlist]
successlist contains the values ['a1o90000001msXwAAI', 'a1o90000001msXxAAI'].
Error Message:
Message: Failed to invoke query. Message payload is of type: ArrayList
How do I resolve this error?
Unfortunately, you can't use ArrayLists as parameters in Salesforce (or Database) queries. You'll have to create the query dynamically with a script component.
Try this:
<scripting:script engine="Groovy">
<![CDATA[def sb = new StringBuilder()
sb.append('Select Id,Billing_Number__c from Call_Log__c')
if (flowVars.successlist != null && !flowVars.successlist.empty) {
sb.append(' where Id in (\'')
for (i in 0 .. flowVars.size()) {
if (i > 0) sb.append('\',\'')
sb.append(flowVars.successlist[i])
}
sb.append('\')')
}
flowVars.query = sb.toString()]]>
</scripting:script>
<sfdc:query query="#[flowVars.query]" doc:name="Salesforce - Query"/>
If you were using a Database, you would have to set the query type as dynamic:
<db:select doc:name="Database">
<db:dynamic-query><![CDATA[#[flowVars.query]]]></db:dynamic-query>
</db:select>
We have used a Java function string.join to convert the list as shown below:
SELECT id FROM User where Id in (#["'" + String.join("','", flowVars.fvCreatedbyIdList) + "'"])
How to look for the value whether it is null or not in JSP. E.g. in below I want to check the description column in pipe table for null values.
String Query1 = "SELECT description FROM pipe where pipe_id='" + id+"' and version_id=2";
SQLResult = SQLStatement.executeQuery(Query1);
SQLResult.first();
description = SQLResult.getString("description");
if(description=="")
{
json_string=json_string+"&desc="+description;
out.println("not null");
} else
{
json_string=json_string;
out.println("null");
}
Well: if (description != null && !description.isEmpty()) ... however are you writing this code within a JSP ? That seems wrong. You should probably do this stuff within a servlet and pass the description as an request attribute to a jsp.
Or you can use StringUtils.isNotEmpty(description).
If you are really using jsp, you should store description in a request attribute and then use <c:if test="${empty description}">.
I use this personal method:
public static boolean isNullOrEmpty(Object obj) {
if (obj == null || obj.toString().length() < 1 || obj.toString().equals(""))
return true;
return false;
}