constant enum value in HQL - java

I have got a working query, which I need to modify by filtering with constant enum value.
Now it looks this way:
public static final String venueQuery =
"select distinct v from package.Venue v "
+ "<some joins here> "
+ "WHERE v.venueType = package.enums.VenueType.VOUCHER_PROVIDER ";
Changing data this way causes
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token
Column definition is like this:
#Enumerated(EnumType.STRING)
#Column(name = "venue_type")
private VenueType venueType;
Enum definition looks this way:
public enum VenueType {
RESTAURANT, BAR, CAFE, FUN_CLUB, VOUCHER_PROVIDER
}
I am sure that other parts of query works fine, because after removing it, no exceptions are thrown.
Are there tricks for setting constant enum value in HQL query?

The preferred way would be to go about adding parameters to the query and pass the enum instance as the parameter value, but if you don't (or can't) make it a parameterized query, you can still do it with String concatenation like this:
public static final String venueQuery =
"select distinct v from package.Venue v "
+ "<some joins here> "
+ "WHERE v.venueType = '" + VenueType.VOUCHER_PROVIDER.name() +"'";
If you want it a compile time constant query String:
public static final String venueQuery =
"select distinct v from package.Venue v "
+ "<some joins here> "
+ "WHERE v.venueType = 'VOUCHER_PROVIDER'";

Related

how to return a list of object which is not entity from a typed query in hibernate?

I need to pull few fields from entity class Employee and add few extra hard coded field and return the result using GROUP BY clause.
Below is the code I tried:
String query = "SELECT emp.category, emp.salary 0 as somevalue, 0 as dummy FROM employee emp "
+ "WHERE emp.date = :date AND emp.class = :class AND emp.classificationDetail.shortDescription = :classificationType GROUP BY emp.category";
TypedQuery<CustomEmployee> typQuery = entityManager.createQuery(query, CustomEmployee.class);
typQuery.setParameter("date", req.getDate());
typQuery.setParameter("class", req.getClass());
return typQuery.getResultList();
But I am getting exception that Cannot create TypedQuery for query with more than one return using requested result type.
How to achieve this.
Thanks.
First check this part: emp.salary 0 as somevalue. This should be either emp.salary as somevalue or 0 as somevalue, but not both.
Define a class like following (to keep it short; I use public properties, but you can change it if you want):
public class CustomEmployee {
public String category;
public Double salary;
public Double dummy;
...
}
The use it in the query as follows:
String query = "SELECT new mypackage.CategorySalary( " +
" emp.category, " +
" emp.salary as somevalue, " +
" 0 as dummy " +
") from ... " +
"WHERE ... ";
TypedQuery<CustomEmployee> typQuery = entityManager.createQuery(query, CustomEmployee.class);

Need to write Spring Data JPA interface method for Query

How can i convert the following native into Spring Data JPA interface method :
#Query(nativeQuery = true,
value = " select count(*) from TABLE "
+ "where ( ColumOne =:xyz or ColumnTwo =:xyz ) "
+ "and STATUS_TX in ('On Hold')")
int countAllByStatusAndName(#Param("xyz") String xyx);
I have written as
Long countByStatusTXAndColumnOnOrColumnTwo (String status, String xyz) . But its not working
I specifically need that or condition between ColumnOne and ColumnTwo.
There seems to be a typo in the method name. ColumnOn instead of ColumnOne. Try Long countByStatusTXAndColumnOneOrColumnTwo (String status, String xyz)

How to resolve spring boot #Value and store it in another string?

#Value("${db.schema.name}")
private String dbSchemaName;
private final String QUERY =
"SELECT * " +
"FROM " + dbSchemaName + ".product " +
"WHERE id = :id";
I use the static String "Query" for multiple methods. The variable dbSchemaName is defined in application.properties (db.schema.name).
public List<Object> loadData(final String id){
final MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("id", id);
return jdbcTemplate.query(QUERY, parameters, new RowMapperResultSetExtractor<>(mapper)));
}
If i execute the Method loadData(...), the dbSchemaName will not be resolved.
If i change the Query from a String variable to a method, the dbSchemaName will be resolved correctly.
private final getQuery(){
"SELECT * " +
"FROM " + dbSchemaName + ".product " +
"WHERE id = :id";
}
but I want to get Access of dbSchemaName in the Query String. For me dbSchemaName is always null in the private final String QUERY. Or is there better design than making it a method?
In your non-working code sample java constructs the QUERY string before Spring has injected the value of ${db.schema.name} into dbSchemaName and it is, therefore, null.
Either stick to your method example or inject the whole query from properties:
#Value("${db.query.value}")
private String query;
Where db.query.value is:
SELECT * FROM ${db.schema.name}.product WHERE id = :id

Sql2o keep returning a same set of data although query is different

I am new to using SQL2O with MySQL, but I am having a weird problem, where different queries return same results. Is SQL2O returning me cached results?
My code looks like this:
String sql = "SELECT * " +
"FROM report_A" +
"ORDER BY :order :sequence "+
"LIMIT :from, :limit";
int limit = 5;
int startIndex = (page-1)*limit;
String sequence = "DESC";
try(Connection con = sql2o.open()) {
if(order.contains("-")){
order = order.replace("-", "");
sequence= " ASC";
}
Query query= con.createQuery(sql)
.addParameter("from", startIndex)
.addParameter("limit", limit)
.addParameter("order", order)
.addParameter("sequence", sequence);
List<ReportA> result = query.executeAndFetch(ReportA.class);
con.close();
The 4 parameters always change, but the output remains the same. I have verified the queries in mysql workbench, the data is different, but SQL2O returns me the same set of data. Am I missing something?
Your query is invalid. It wont compile and throw an Sql2oException on execution.
The problem is, basically, that you can use parameters only for values, not for table names, column names or other keywords like "ASC". Changing those would change the structure of the query.
It's possible to construct queries with variable structure by good old string concatenation, i.e.
String sql = "SELECT * " +
"FROM report_A" +
"ORDER BY " + order " " + SEQUENCE +
"LIMIT :from, :limit";
and then
query(sql)
.addParameter("from", from)
.addParameter("limit", limit)
.executeAndFetch(...)

Malformed query using IN

I have this structure:
public enum SaleItemType {
CRUISE,
DAILY_HOSTING
}
public class Estimate {
...
private List<SaleItemType> interestedSaleItemTypes;
#Column(name = "sale_item_type")
#CollectionTable(name = "estimate_sale_item_type", joinColumns = #JoinColumn(name = "estimate_id"))
#ElementCollection(targetClass = SaleItemType.class)
#Enumerated(EnumType.STRING)
public List<SaleItemType> getInterestedSaleItemTypes() {
return interestedSaleItemTypes;
}
}
And i'm trying to do a simple query:
String q = "FROM " + Estimate.class.getSimpleName() + " e" + " WHERE e.interestedSaleItemTypes IN :a";
TypedQuery<Estimate> query1 = getEm().createQuery(q, Estimate.class);
query1.setParameter("a", EnumSet.of(SaleItemType.CRUISE));
query1.getResultList();
I'm getting this query(and error) on the log:
DEBUG SQL:92 - select estimate0_.id as id1_25_, estimate0_.average_ticket as average_2_25_, estimate0_.description as descript3_25_, estimate0_.end_date as end_date4_25_, estimate0_.pax_quantity as pax_quan5_25_, estimate0_.start_date as start_da6_25_ from estimate estimate0_ cross join estimate_sale_item_type interested1_ where estimate0_.id=interested1_.estimate_id and (. in (?))
DEBUG SqlExceptionHelper:124 - could not extract ResultSet [n/a]
org.postgresql.util.PSQLException: No value specified for parameter 1.
Why hibernate is doing this query?
Im using Hibernate 5.1 Final
The IN expression can be used to test if a value is in a collection but interestedSaleItemTypes is not a simple value but itself a collection. Therefore use MEMBER OF:
String q = "FROM Estimate e WHERE :a MEMBER OF e.interestedSaleItemTypes";
TypedQuery<Estimate> query1 = getEm().createQuery(q, Estimate.class);
query1.setParameter("a", SaleItemType.CRUISE);
Did you try to put parenthesis in your IN clause?
I don't know if it's required, but in all tutorials that I found, always had the parenthesis. http://www.postgresqltutorial.com/postgresql-in/
Also, as the IN clause is expecting a list of values you can use the setParameterList instead of setParameter.
Try this:
String q = "FROM " + Estimate.class.getSimpleName() + " e" + " WHERE e.interestedSaleItemTypes IN (:a)";
TypedQuery<Estimate> query1 = getEm().createQuery(q, Estimate.class);
query1.setParameterList("a", EnumSet.of(SaleItemType.CRUISE));
query1.getResultList();

Categories