I have the hql query that I am executing but receive an error that I don't really understand the cause of.
This is my code:
#Override
public List<StaffRequest> getStaffLeaveRequest(String userID, Date startDate, Date endDate)
{
Session currentSession = sessionFactory.getCurrentSession();
List<StaffRequest> results =
currentSession.createQuery("select new com.timesheet_Webservice.CustomEntity.StaffRequest(lr.leave_ID, lr.leave_Employee, concat(s.staff_First_Name, ' ', s.staff_Last_Name), "
+ "(lr.leave_Days*8.5), lr.leave_Comments, '1805', concat(pro.project_Pastel_Prefix, ' - ', pro.project_Description), lr.leave_Start, lr.leave_End, lr.leave_IsApproved, "
+ "(select lt.leaveType_Description from LeaveType lt where lt.leaveType_ID = lr.leave_Type)) "
+ "from Staff s, Project pro, Leave lr "
+ "where lr.leave_Employee = s.staff_Code and pro.project_Code = 1805 and lr.leave_Approved = :userID and lr.leave_IsApproved = 0 and s.staff_IsEmployee <> 0 "
+ "and lr.leave_Start between :startDate and :endDate "
+ "order by concat(s.staff_First_Name, ' ', s.staff_Last_Name)")
.setParameter("userID",userID).setParameter("startDate", startDate).setParameter("endDate", endDate).getResultList();
return results;
}
I get this error on the webpage when trying to execute it:
org.hibernate.exception.SQLGrammarException: could not extract
ResultSet
And also this console error:
ERROR: You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near 'Leave leave2_ where leave2_.Leave_Employee=staff0_.Staff_Code
and project1_.Proj' at line 1
It seems to indicate some fault at the where clause, but I don't see anything particularly wrong.
UPDATE:
Entity classes
Project
#Entity
#Table(name="project")
public class Project {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Project_Code")
public int project_Code;
#Column(name="Project_Customer")
public int project_Customer;
//A lot more attributes...
}
Staff
#Entity
#Table(name="staff")
public class Staff
{
#Id
#Column(name="Staff_Code")
public String staff_Code;
...
}
1) As you using java.util.Date for Leave.leave_Start, you should annotate with proper #Temporal value:
#Temporal(TemporalType.TIMESTAMP)
#Column(name="Leave_Start")
Date leave_Start;
2) When setting your query date parameters, try using:
.setDate("startDate", startDate)
or
.setParameter("startDate", startDate, TemporalType.TIMESTAMP)
Ok, after much testing I discovered the reason for the error. For some unknown reason the query seems to have a problem with the name of the referenced table 'leave' and produces the error whenever I try to retrieve data from it. If I however rename the table to something as simple as 'leaves' then the query executes successfully. Anyone might know why this is?
Apparently JPA follows some rule or convention of variable names and does not accept "_" and for some reason does not accept intermediate capital letters... It worked for me by changing all variables to lowercase
Related
I have a spring boot app connected to oracle DB.
I am trying to order a list of records and select the top most record.
I wrote a JPA query as below but it fails.
#Query("SELECT id FROM UploadedFile uploadedFile "
+ "WHERE uploadedFile.p_file_type = 'branch' "
+ "and p_file_status='Processed' "
+ "and p_is_file_process_with_error = 0 "
+ "order by c_created_date desc "
+ "FETCH FIRST 1 rows only ")
public String findLatestBranchCodeFile();
The error received was
creating bean with name 'uploadedFileRepo': Invocation of init method
failed; nested exception is java.lang.IllegalArgumentException:
Validation failed for query for method public abstract
java.lang.String
com.rhb.pintas.repo.UploadedFileRepo.findLatestBranchCodeFile()!
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token:
FETCH near line 1, column 204 [SELECT id FROM
com.rhb.pintas.entities.UploadedFile uploadedFile WHERE
uploadedFile.p_file_type = 'branch' and p_file_status='Processed' and
p_is_file_process_with_error = 0 order by c_created_date desc FETCH
FIRST 1 rows only ] -> [Help 1]
The issue seems to be with fetch,not sure whats wrong.
It seems you are mixing HQL and native query dialects:
If this will be a naviveQuery (like most of the columns would mention), then replace the entity name with table name and add nativeQuery option. And because You are using only a single table, You can skip the alias name:
#Query("SELECT id FROM uploaded_file "
+ "WHERE p_file_type = 'branch' and p_file_status='Processed' and "
+ "p_is_file_process_with_error = 0 "
+ "order by c_created_date desc "
+ "FETCH FIRST 1 rows only ", nativeQuery = true)
public String findLatestBranchCodeFile();
If You want to keep it as a HQL, then replace all column names with entity property names, like p_file_type > fileType (I guess column names). Secondly You will need to pass a Pageable parameter, to replace Your 'Fetch first' statement.
You can find more materials here:
Bealdung
NativeQ
StackOverflow
You are trying to execute SQL query, in this case you need to add nativeQuery=true attribute to #Query annotation
UPD.
got confused because FETCH FIRST - is a SQL syntax, for JPA way please check another solution - it is possible to return list with at most one element.
I guess, you can try passing pagable to limit result set size and unlimit your query:
public String findLatestBranchCodeFile(Pageable pageable); // pass new PageRequest(0,1)
When Im trying to call JPA function this statement I got an error: syntax error at or near ":"
public interface BcaTestRepository extends CrudRepository<InBodyBCA, Long> {
#Query(value = "SELECT * FROM in_body_bca bca WHERE person_id = :personId " +
"AND to_timestamp(bca.datetimes::text, 'YYYYMMDDHH24MISS') BETWEEN :startRange AND :endRange",
nativeQuery = true)
List<InBodyBCA> findAllByPersonId(#Param("personId") Long personId,
#Param("startRange") LocalDateTime startRange,
#Param("endRange") LocalDateTime endRange);
But in PgAdmin the query works fine
SELECT id, to_timestamp(datetimes::text, 'YYYYMMDDHH24MISS') as dt FROM in_body_bca WHERE to_date(datetimes::text, 'YYYYMMDDHH24MISS')
BETWEEN '2018-05-07' AND '2019-05-07' ORDER BY to_date(datetimes::text, 'YYYYMMDDHH24MISS') DESC ;
You use the double colon here: bca.datetimes::text. JPA would look for text variable name.
You need to escape it:
bca.datetimes\\:\\:text
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();
I have a database showing the relationship much more like this
I want to get information out of two table gmail and bloggerwith conditions blog[blogger] and user[gmail] value exists in table md_parse_blogger
I want to know how to make a correct syntax where,please help me
public List showDatawebA(String blog, String url) {
String sql = "FROM MdParse g,MdBlogger b,MdParseBlogger pb"
+ " WHERE pb.mdBlogger=:blog and pb.mdParse=:url";
Query createQuery = currentSession.createQuery(sql);
createQuery.setParameter("blog", blog);
createQuery.setParameter("url", url);
return createQuery.list();
}
With mdBlogger,mdGmail is attribute class MdParseBlogger,
public class MdParseBlogger implements java.io.Serializable {
private MdParseBloggerId id;
private MdBlogger mdBlogger;
private MdParse mdParse;
...........
}
ERROR
Exception in thread "main" org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 2
at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterDescriptor(ParameterMetadata.java:89)
at org.hibernate.engine.query.spi.ParameterMetadata.getOrdinalParameterExpectedType(ParameterMetadata.java:109)
at org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:507)
at org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:479)
at dbUtility.DBTable.showDataweb(DBTable.java:76)
at dbUtility.DBTable.main(DBTable.java:83)
Picked up _JAVA_OPTIONS: -Xmx512M
You mixed named and ordinal parameters. It should be either
String sql ="FROM MdGmail g,MdBlogger b,MdParseBlogger pb"
+ " WHERE pb.mdBlogger=? and pb.mdGmail=?";
Query createQuery = currentSession.createQuery(sql);
createQuery.setParameter(1, blog);
createQuery.setParameter(2, url);
Or
String sql ="FROM MdGmail g,MdBlogger b,MdParseBlogger pb"
+ " WHERE pb.mdBlogger=:blog and pb.mdGmail=:url";
Query createQuery = currentSession.createQuery(sql);
createQuery.setParameter("blog", blog);
createQuery.setParameter("url", url);
I'm doing a school project so I'm really not an advanced programmer and need a little help with a query that I need to make.
My db structure looks like this.
RECIPE table:
ID BIGINT 19
DESCRIPTION CLOB 2147483647
NAME VARCHAR 255
INGREDIENT table:
ID BIGINT 19
NAME VARCHAR 255
RECIPE_INGREDIENT table:
RECIPE_ID BIGINT 19
INGREDIENTS_ID BIGINT 19
This is my model class Recipe
#Entity
public class Recipe extends Model {
#ManyToMany(cascade=CascadeType.ALL)
public List<Ingredient> ingredients;
#Required
#Unique
public String name;
#Lob
#Required
public String description;
This is my model class Ingredient
#Entity
public class Ingredient extends Model {
#Required
#Unique
public String name;
The query I want to make is... I have a string with comma separated ingredients like milk,flour,egg for example. With that string I'd like to fetch all recipes which has exact those ingredients, lets say one Recipe only has flour as ingredient then that's true. Also a recipe with all mentioned etc etc.
I've modified a query string I found yesterday(can't remember where) but I can't get it to work.
I get this error:
IllegalArgumentException occured : org.hibernate.hql.ast.QuerySyntaxException: unexpected token: on near line 1, column 68 [select Recipe.name from models.Recipe inner join Recipe_Ingredient on Recipe.ID = Recipe_Ingredient.Recipe_ID inner join Ingredient on Recipe_Ingredient.Ingredient_ID = Ingredient.ID where Ingredient.name in ( 'milk') group by Recipe.name having count(*) = 2]
Any help would be much appreciated! And sorry if I made any mistakes with this post. It is my first here :)
Edit:
Query right now looks like this:
Query query = JPA.em().createQuery("SELECT Recipe.name "
+ "FROM Recipe INNER JOIN "
+ "Recipe_Ingredient ON Recipe.ID = Recipe_Ingredient.Recipe_ID "
+ "INNER JOIN Ingredient "
+ "ON Recipe_Ingredient.Ingredient_ID = Ingredient.ID "
+ "WHERE Ingredient.name "
+ "IN ("+ingredientsCSV+") "
+ "GROUP BY Recipe.name HAVING count(*) = 2");
I don't think you can do that with a simple query.
Why:
- You need to have way yo know if all ingredients are within your ingredient string.
Using having will not solve the problem is different recipes will have different amount of ingredients.
I'm not very familiar with how JPA works, but in pure sql for example mysql you could use a view to organize the data before you process it with a new query.
I'm Sorry that I can't help you with that query in JPA.
Looks like you need quotes on:
... Ingredient.name in ('milk', 'flour', 'egg') group by....