How to translate this SQL (or similar) to Criteria JPA - java

I have this SQL and need to parse to Criteria JPA. I read than I can't use UNION in JPA, so I need a similar solution.
I have 3 tables (with same fields) and need to union for print in datatable.
The query is:
SELECT * FROM (
SELECT id, project_id, start_date, end_date, 'cs' FROM construction_shares
UNION
SELECT id, project_id, start_date, end_date, 'ips' FROM intervention_pr_shares
UNION
SELECT id, project_id, start_date, end_date, 'is' FROM intervention_shares
) AS t ORDER BY START_DATE ASC;
Can someone help me?
Thanks a lot!

Criteria JPA dont support UNION, you can try two options.
Create a native query and execute from entityManager with a List of POJOS as result.
Throw 3 Querys like this:
SharesPojo:
private Integer id;
private Integer projectId;
private Date startDate;
private Date endDate
public SharesPojo(Integer id, Integer projectId, Date startDate, Date endDate);
DAO:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SharesPojo> csQuery = cb.createQuery(SharesPojo.class);
Root<ConstructionShares> csRoot = csQuery.from(ConstructionShares.class);
csQuery.multiselect(
csRoot.get(ConstructionShares_.id)
csRoot.get(ConstructionShares_.projectId)
csRoot.get(ConstructionShares_.startDate)
csRoot.get(ConstructionShares_.endDate)
);
CriteriaQuery<SharesPojo> ipsQuery = cb.createQuery(SharesPojo.class);
Root<InterventionPrShares> ipsRoot = ipsQuery.from(InterventionPrShares.class);
ipsQuery.multiselect(
ipsRoot.get(InterventionPrShares_.id)
ipsRoot.get(InterventionPrShares_.projectId)
ipsRoot.get(InterventionPrShares_.startDate)
ipsRoot.get(InterventionPrShares_.endDate)
);
CriteriaQuery<SharesPojo> isQuery = cb.createQuery(SharesPojo.class);
Root<InterventionShares> isRoot = isQuery.from(InterventionShares.class);
isQuery.multiselect(
isRoot.get(InterventionShares_.id)
isRoot.get(InterventionShares_.projectId)
isRoot.get(InterventionShares_.startDate)
isRoot.get(InterventionShares_.endDate)
);
List<SharesPojo> unionList = new ArrayList<>();
unionList.addAll(em.createQuery(csQuery).getResultList());
unionList.addAll(em.createQuery(ipsQuery).getResultList());
unionList.addAll(em.createQuery(isQuery).getResultList());

Related

How can I group by a date(timestamp_field ) in QueryDSL 5.0.0

How can I write a queryDSL query for the following MySQL query:
SELECT
u.id as user_id,
count(*) as total_completed
date(o.created_at) date
FROM
users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.status='COMPLETED'
GROUP BY date(o.created), u.id
I am mainly interested in implementing the date(timestamp_field) so that I can use it for aggregating over entire dates.
This is my OrderEntity:
...
#Table(name = "orders")
public class OrderEntity extends BaseEntity {
#Id
#Column(nullable = false)
private String id;
private Instant createdAt;
...
}
This is in QOrderEntity
public final DateTimePath<java.time.Instant> createdAt = createDateTime("createdAt", java.time.Instant.class);
Basically, how can I truncate/type cast the SQL Timestamp field to DATE in the SELECT query. It needs to be done on the WHERE clause, GROUP BY clause, and SELECT clause
I tried this link here: QueryDSL - select rows with date from timestamp column
You can either use between or a custom expression if you use Querydsl SQL
Something like this
DateExpression<Date> converted = DateTemplate.create(Date.class, "convert(date, {0})",
The API doesn't have create() method, maybe it was removed.

Hibernate mapping non-entity classes. org.hibernate.MappingException: Unknown entity: java.time.LocalDateTime

I have a table [order_id, guest_id, maintenance_id, order_timestamp], and I want to select list of timestamps, when the guest_id ordered maintenance_id.
I simply tried to select LocalDateTime with the code below, but hibernate threw:
Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown entity: java.time.LocalDateTime
public List<LocalDateTime> getGuest2MaintenanceOrderTime(long guestId, long maintenanceId) {
List<?> resultList = entityManager.createNativeQuery(
"SELECT * FROM guest_2_maintenance where guest_id = ? and maintenance_id = ?", LocalDateTime.class)
.setParameter(1, guestId)
.setParameter(2, maintenanceId)
.getResultList();
return (List<LocalDateTime>) resultList;
It seems strange to me to create separate class for holding date, and annotate it with #Entity. How to select LocalDateTime and map it to a new LocalDateTime object?
Mapping LocalDateTime as field of #Entity object works fine, but in my case this table field does not belong to any #Entity
Thanks to #akortex and #Human Bean for responsing but I managed to make it works somehow this way:
public List<LocalDateTime> getGuest2MaintenanceOrderTime(long guestId, long maintenanceId) {
List<Timestamp> resultList = entityManager.createNativeQuery(
"SELECT order_timestamp FROM guest_2_maintenance where guest_id = ? and maintenance_id = ?")
.setParameter(1, guestId)
.setParameter(2, maintenanceId)
.getResultList();
List<LocalDateTime> localDateTimeList = new ArrayList<>();
resultList.forEach(timestamp -> {
localDateTimeList.add(timestamp.toLocalDateTime());
});
return localDateTimeList;
}
Your mistake is that you do 'select * ...'
There are two ways to solve your problem:
Select only time field
List<LocalDateTime> resultList = entityManager.createNativeQuery(
"SELECT order_timestamp FROM guest_2_maintenance where guest_id = ? and maintenance_id = ?", LocalDateTime.class)
.setParameter(1, guestId)
.setParameter(2, maintenanceId)
.getResultList();
return resultList;
}
Or you should use an entity and then retrieve order_timestamp field from it. For example

Can we call or combine Select and a procedure in Spring data jpa #Query

I have a procedure written in database. my_procedure(val1, val2)
So, lets say I have a database query like this:
select field1 as fieldName, field2 as fieldId
(select * from mydb.my_procedure(id)) as aValue // A procedure call
from mydb.my_table
I want to convert this to Spring's Data JPA #Query. Something like this:
#Query (" HERE I WANT THE ABOVE QUERY TO IMPLEMENT")
public List<MyTable> getDetails ()
Are we allowed to do this?
UPDATE
For example I have below query which I want to convert.
select id, name, roll,
(select * from db.calculate_fee (date, id)) fee
from Student
where id = 1 AND roll = 5
I want to do something like
#Query("SELECT student, (select * from db.calculate_fee (date, id) fee FROM Student student "
+ "WHERE student.id=:id, "
+ "AND student.name=:roll")
public List<Student> getDetails(#Param("id") Integer id, #Param("roll") Integer roll);
Is there anyway to do this?
Have you tried it with a native query?
#Query(nativeQuery = true, value = "select field1 as fieldName, field2 as fieldId...")
List<MyTable> getDetails();
(by the way, public is not needed for 'getDetails' as Repositories are interfaces)
#NamedStoredProcedureQueries({
#NamedStoredProcedureQuery(name = "getAllEmployees",
procedureName = "get_all_employees",
resultClasses = Employees.class)
})
#Procedure(name = "getAllEmployees")
List<Employees> getAllEmployees();
Complete tutorial

Hibernate - filter Single Column data using date where clause

Lets say One table ABC having two column i.e. ID & CREATED_DATE
I want to fetch those ID which is created lets say '09-11-2017' and '09-17-2017'
Below SQL query working fine but I want to implement same logic using hibernate.
select ID from ABC where between TO_DATE('09-11-2017', 'MM-DD-YYYY') AND TO_DATE('09-17-2017', 'MM-DD-YYYY')
My code is not working.
public List getData(final Date startDate, final Date endDate){
String sqlString = "select ID from ABC where CREATED_DATE between :startDate and :endDate";
SQLQuery query = getSession().createSQLQuery(sqlString);
query.setParameter(CREATED_DATE);
return query.list();
}
You are missing End date parameter :
query.setParameter(CREATED_DATE, startDate);
query.setParameter(END_DATE, endDate);
It not work because you don't set the correct parameters :
String sqlString = "select ID from ABC where CREATED_DATE between :startDate and :endDate";
SQLQuery query = getSession().createSQLQuery(sqlString);
query.setParameter("startDate ", start_date);
query.setParameter("endDate", end_date);
return query.list();
The parameters must match the string on the query
Try this:
public List getData(final Date startDate, final Date endDate){
String sqlString = "select ID from ABC where CREATED_DATE between :startDate and :endDate";
SQLQuery query = getSession().createSQLQuery(sqlString);
query.setParameter("startDate",startDate);
query.setParameter("endDate",endDate);
return query.list();
}
--
pscar13

hibernate "where" query only works for id field

I have a problem with a Hibernate query that looks as follows:
List persons = getList("FROM creator.models.Person p WHERE p.lastName="+userName);
(the getList(String queryString) method just executes the query using a session factory.)
This is my person class:
#Entity
#Table(name="persons")
public class Person{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(name="first_name", nullable=false, updatable=true)
private String firstName;
#Column(name="last_name", nullable=false, updatable=true)
private String lastName;
/// etc
And this is the table:
CREATE TABLE persons(
id INTEGER NOT NULL AUTO_INCREMENT,
first_name CHAR(50),
last_name CHAR(50),
abbreviation CHAR(4),
PRIMARY KEY (id)
);
Searching for a person with the name TestName, I get an exception with this message:
org.hibernate.exception.SQLGrammarException: Unknown column 'TestName' in 'where clause'
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
//etc
The query created by Hibernate looks like this:
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select person0_.id as id8_, person0_.abbreviation as abbrevia2_8_, person0_.first_name as first3_8_, person0_.last_name as last4_8_ from persons person0_ where person0_.last_name=TestName
Dec 10, 2012 5:14:26 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
Searching for the id (...WHERE p.id="3") works fine, by the way!
I hope somebody knows what is going wrong because for me the query looks right and I can't find out why the lastName is seen as a column name suddenly.
You need to put userName in quotes:
"FROM creator.models.Person p WHERE p.lastName='"+userName+"'";
Or (which is much better) to use parameters
replace your hql with:
Query query = session.createQuery("from creator.models.Person p where p.lastName = ?")
.setParameter(0, userName);
List persons = query.list();
that way you also prevent sql-injection.
you need to wrap your parameter with single quotes:
List persons = getList("FROM creator.models.Person p WHERE p.lastName='"+userName+"'");
but much better with a parameterized query:
String hql = "FROM creator.models.Person p WHERE p.lastName= :userName";
Query query = session.createQuery(hql);
query.setString("userName",userName);
List results = query.list();

Categories

Resources