How can I use JPA do this SQL query? - java

Hello everyone I try do this query "SELECT SUM(cevecoin) FROM coin where clid="ABC" in JPA but it's no working. Can somebody help me?
public Integer SumCoin(String Clid) {
CriteriaBuilder builder =getSession().getCriteriaBuilder();
CriteriaQuery<CoinBean> criteria =builder.createQuery(CoinBean.class);
Root<CoinBean> root = criteria.from(CoinBean.class);
criteria.select(builder.sum(root.<Integer>get("clid")).as(CoinBean.class)).where(builder.equal(root.get("clid"),Clid));
return getSession().createQuery(criteria).getSingleResult().getCevecoin();
}

try this:
CriteriaBuilder builder =getSession().getCriteriaBuilder();
// the type of query criteria must correspond to the result we want to obtain
CriteriaQuery<BigDecimal> criteria = builder.createQuery(BigDecimal.class);
Root<CoinBean> root = criteria.from(CoinBean.class);
// use multiselect and sum the field cevecoin
criteria.multiselect(builder.sum(root.get("cevecoin")))
criteria.where(builder.equal(root.get("clid"),Clid));
return getSession().createQuery(criteria).getSingleResult();

Related

Hibernate 3 - 5 Migration. Org.hibernate.Criteria: Changing createCriteria(String association, String alias) to standard JPA using CriteriaBuilder

So I have this Hibernate Criteria code I want to change using JPA, I have made changes to it referenced below but I can't seem to find a replacement to creating a Criteria from "detCrit" with the method detCrit.createCriteria(String association, String alias) using JPA's CriteriaBuilder. if anyone knows an alternative solution I will be grateful.
\\\Initial Hibernate Criteria code
Criteria deCrit = currentSession().createCriteria(first.class, "firstbasic");
Criteria secondThemeCrit = detCrit.createCriteria("secondBasic","sc");
Criteria thirdThemeCrit = secondThemeCrit.createCriteria("thirdBasic");
\\\Partially changed code with JPA
CriteriaBuilder builder = Session.getCriteriaBuilder();
CriteriaQuery<First> deCrit = builder.createQuery(First.class);
Root<First> first = detCrit.from(First.class);
first.alias("firstbasic");
I don't know how you use this code afterwards, but I assume within a subquery? If so, you can correlate the root in the subquery and the just call join on the correlated object which should result in the same:
CriteriaBuilder builder = Session.getCriteriaBuilder();
CriteriaQuery<First> deCrit = builder.createQuery(First.class);
Root<First> first = detCrit.from(First.class);
Subquery<Integer> subquery = deCrit.subquery(Integer.class);
Root<First> correlatedFirst = subquery.correlate(first);
Join<First, Second> second = correlatedFirst.join("second");

JPA Criteria query with inner join of aggregation

I'm trying to write a CriteriaQuery which will query latest observation for each city. City is defined by city_code field, while latest record is defined by observation_time field.
I can easily write it in a plain SQL, but I cant understand how to do it with jpa criteria api.
select distinct m.* from
(select city_code cc, max(observation_time) mo
from observations group by city_code) mx, observations m
where m.city_code = mx.cc and m.observation_time = mx.mo`
It is possible when You are open for loose efficiency.
So first let's transform our query to logical equivalent one:
select distinct m.* from observations m where
m.observation_time = (select max(inn. observation_time) from observations inn
where inn.city_code = m.city_code);
then let's translate it to JPA CriteriaQuery:
public List<Observation> maxForEveryWithSubquery() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Observation> query = builder.createQuery(Observation.class);
Root<Observation> observation = query.from(Observation.class);
query.select(observation);
Subquery<LocalDateTime> subQuery = query.subquery(LocalDateTime.class);
Root<Observation> observationInner = subQuery.from(Observation.class);
subQuery.where(
builder.equal(
observation.get(Observation_.cityCode),
observationInner.get(Observation_.cityCode)
)
);
Subquery<LocalDateTime> subSelect = subQuery.select(builder.greatest(observationInner.get(Observation_.observationTime)));
query.where(
builder.equal(subSelect.getSelection(), observation.get(Observation_.observationTime))
);
TypedQuery<Observation> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
}
Unfortunately JPA does not support sub queries in FROM clause. You need to write a native query or use framework like FluentJPA.

Syntax where clause in consultation with criteria

I need to put a where clause in my query, but I'm not hitting the correct syntax.
/*
* Support listing and POSTing back Origem entities (e.g. from inside an
* HtmlSelectOneMenu)
*/
public List<Origem> getAll()
{
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Origem> criteria = cb.createQuery(Origem.class);
Root<Origem> root = criteria.from(Origem.class);
return this.entityManager.createQuery(
criteria.select(root).where())
.getResultList();
}
In my where clause want to bring all "origem" with id equal to the logged in user.
Something like this:
Ex: select * from origin where origem.id = loginBean.origem.getId
Simply use criteria.add(Restrictions.eq()) to your criteria and I think if the id is unique you need to use .uniqueResult() to get the wanted result from your criteria, your code should be like this:
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
Criteria cr = cb.createCriteria(Origem.class);
// add the restriction here
cr.add(Restrictions.eq("id", loginBean.origem.getId));
Origem root = (Origem) cr.uniqueResult();
Use criteria.addRestrictions(Restrictions.eq("propertyName","propertyValue");
public List getAll(long idFromLoginBeanOrigin)
{
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Origem> criteria = cb.createQuery(Origem.class);
criteria.add(Restrictions.eq("origem.id", idFromLoginBeanOrigin));
Root<Origem> root = criteria.from(Origem.class);
return this.entityManager.createQuery(
criteria.select(root).where())
.getResultList();
}
I type it now do maybe have a typo, please check !

JPA Criteria Query distinct

I am trying to write a distinct criteria query, using:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<RuleVar> query = builder.createQuery(RuleVar.class);
Root<RuleVar> ruleVariableRoot = query.from(RuleVar.class);
query.select(ruleVariableRoot.get("foo").<String>get("foo")).distinct(true);
Based on the example in the javadoc for CriteriaQuery.select()
CriteriaQuery<String> q = cb.createQuery(String.class);
Root<Order> order = q.from(Order.class);
q.select(order.get("shippingAddress").<String>get("state"));
However, this gives me an error:
The method select(Selection<? extends RuleVar>) in the type CriteriaQuery<RuleVar> is not applicable for the arguments (Path<String>)
Can someone please point out what I am doing wrong? Or how to get a Selection object from a Path?
I got it. The problem was my CriteraQuery needed to be of type String. This works:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<String> query = builder.createQuery(String.class);
Root<RuleVar> ruleVariableRoot = query.from(RuleVar.class);
query.select(ruleVariableRoot.get(RuleVar_.varType)).distinct(true);

JPA / Hibernate: CriteriaBuilder - How to create query using relationship object?

I have the following four tables:
SCHEDULE_REQUEST TABLE:
ID,
APPLICATION_ID (FK)
APPLICATION TABLE:
ID,
CODE
USER_APPLICATION TABLE:
APPLICATION_ID (FK),
USER_ID (FK)
USER TABLE:
ID,
NAME
Now I wanted to create a CriteriaBuilder where condition is to select ScheduleRequests for specified user Ids.
I have the following codes:
List<User> usersList = getSelectedUsers(); // userList contains users I wanted to select
CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder();
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class);
Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class);
criteria = criteria.select(scheduleRequest);
ParameterExpression<User> usersIdsParam = null;
if (usersList != null) {
usersIdsParam = builder.parameter(User.class);
params.add(builder.equal(scheduleRequest.get("application.userApplications.user"), usersIdsParam));
}
criteria = criteria.where(params.toArray(new Predicate[0]));
TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria);
// Compile Time Error here:
// The method setParameter(Parameter<T>, T) in the type TypedQuery<ScheduleRequest> is not
// applicable for the arguments (ParameterExpression<User>, List<User>)
query.setParameter(usersIdsParam, usersList);
return query.getResultList();
Can you please help me how to pass query filter to a relationship object?
I think what I did in "application.userApplications.user" is wrong?
Please really need help.
Thank you in advance!
Using the canonical Metamodel and a couple of joins, it should work. Try if you get some hints from the following pseudo-code (not tested):
...
Predicate predicate = cb.disjunction();
if (usersList != null) {
ListJoin<ScheduleRequest, Application> applications = scheduleRequest.join(ScheduleRequest_.applications);
ListJoin<Application, UserApplication> userApplications = applications.join(Application_.userApplications);
Join<UserApplication, User> user = userApplications.join(UserApplication_.userId);
for (String userName : usersList) {
predicate = builder.or(predicate, builder.equal(user.get(User_.name), userName));
}
}
criteria.where(predicate);
...
In order to understand Criteria Queries, have a look at these tutorials:
http://www.ibm.com/developerworks/java/library/j-typesafejpa/
http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html
The second link should also guide you on how to use Metamodel classes, that should be built automatically by the compiler / IDE.

Categories