Customer{
String customerName
#OneToMany
Set users;
}
User{
String userName;
}
when i do this:
select c.customerName as customerName ,concat(u.userName) as userNames from Customer c join c.users as u
hibernate don't return the result i expected.
Unfortunately hibernate does not have an SQL aggregate function that combines strings. There is no standard SQL aggregate function for this either so each database tends to have it's own. An example would be NexusDB 3.x's LIST() which compiles a comma-separated list of non-null values in the set.
SELECT c.customerName as customerName , LIST(u.userName) as userNames
FROM Customer c
JOIN c.users as u
GROUP BY c.customerName;
Related
I am assuming a setup as described in: https://howtodoinjava.com/hibernate/hibernate-one-to-many-mapping-using-annotations/
Employee:
#JoinColumn(name="EMPLOYEE_ID")
private Set<AccountEntity> accounts;
Account:
#ManyToOne
private EmployeeEntity employee;
Using JPA/Hibernate, how can I fetch results using a WHERE condition that applies to Account. In other words, query something like Select all employees with accounts with sales > 0 or similar.
I'm assuming sales column as INT in account table.
you can write a query like following:
TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e JOIN Account a ON e.id = a.accounts.employee_id WHERE a.sales > :sales", Employee.class);
query.setParameter("sales", salesInput);
List<Employee> items = query.getResultList();
I would recommend you to go through this tutorial to learn about CRUD operations in Hibernate Associations
https://www.dineshonjava.com/spring-crud-example-using-many-to-one/
I have a class named Submission and another SubmissionDAO for the repository. The submission class has a number of fields such as id, author, title,...
What I want to do is search through the database and get a list of (count, author) pairs for each author value in the database.
I made a query
#Query(value = "select author, count(*) from submissions GROUP BY author order by count(author) desc", nativeQuery = true)
List<Submission> findByAuthorOccurance();
Obviously, this doesn't work because it can't put the count value in the Submission object.
My question is how would I go about getting this pair of values back to my controller?
I've tried searching but nothing comes up.
In case anyone comes here in the future for whatever reason, I figured my problem out.
When you specify a range of data points to get from the query (ie author and count), it groups the values into object arrays (Object[]) and puts those in a normal List.
So my code ended up being like this:
#Query(value = "select author, count(*) from submissions GROUP BY author order by count(author) desc", nativeQuery = true)
List<Object[]> findByAuthorOccurance();
For the query and
List<Object[]> map =submissionRepository.findByAuthorOccurance();
for(Object[] objs : map){
System.out.println((String)objs[0]+" : "+(BigInteger)objs[1]);
}
To get the data.
I have two tables linked by another table like this:
ROLES(RoleID, RoleName)
EMPLOYEES(EmployeeID, E_Name, Address)
ROLE_EMPLOYEES(RoleID#,EmployeeID#).
I want a query that retrieves all from EMPLOYEES and RoleID from ROLES and displays on Java form.
I have tried this but does not work:
rs=st.executeQuery("SELECT EMPLOYEES.*, ROLES.* FROM EMPLOYEES JOIN ROLES");
while(rs.next()){
//MOVE THE CURSOR TO THE FIRST RECORD AND GET DATA
int employeeid=rs.getInt("EmployeeID");
String id=Integer.toString(employeeid);
String name=rs.getString("E_Name");
String addr=rs.getString("Address");
String s = rs.getString("RoleID");
jComboBox1.addItem(s.trim());
//DISPLAY THE FIRST RECORD IN THE TEXT FIELD
txtEmpNumber.setText(id);
txtEmpName.setText(name);
txtEmpAddress.setText(addr);
jComboBox1.setSelectedItem(s);
}
You may try this:
SELECT
EM.*, RL.*
FROM
EMPLOYEES EM
INNER JOIN
ROLE_EMPLOYEES REM ON REM.EmployeeID = EM.EmployeeID
INNER JOIN
ROLES RL ON RL.RoleID = REM.RoleID
Just by writing the keyword JOIN the db-engine does not know in which way it should join the data of the tables; unless you want to retrieve a cartesian product (that's not your case), you need to explicitly set the criteria by using the ON clause.
Consider a class:
class Employee{
Integer empId,
//many other fields
}
I need a DAO method as shown below
List<Integer> getAllEmployeeIds(){
//??
}
I dont want List<Employee> and (NEW EDIT) Set<Intger>
How can i do that in hibernate?Am using hbm files for mapping
Like this. Also, I recommend use querydsl to make it type-safe.
List<Integer> getAllEmployeeIds(){
return (List<Integer>)createQuery("select e.empId from Employee e").list();
}
use an hql query and do something like
String hql = "select E.empId from Employee E";
Query query = session.createQuery(hql);
List<Integer> ids = query.list();
follow the documentation from here.
I have the following tables
CREATE TABLE "COMPANIES" (
"ID" NUMBER NOT NULL ,
"NAME" VARCHAR2 (100) NOT NULL UNIQUE
)
/
CREATE TABLE "COMPANIESROLES" (
"ID" NUMBER NOT NULL ,
"COMPANYID" NUMBER NOT NULL ,
"ROLENAME" VARCHAR2 (30) NOT NULL
)
/
CREATE TABLE "ROLES" (
"NAME" VARCHAR2 (30) NOT NULL
)
/
This structure represents a number of companies and the roles allowed for each company. For these tables, there are the corresponding Hibernate objects:
public class Company implements Serializable {
private Long id;
private String name;
private Set<Role> companyRoles;
//(getters and setters omitted for readability)
}
public class Role implements Serializable {
private String name;
//(getters and setters omitted for readability)
}
Finding out all companies, which have a specific role using the Hibernate Criteria API is no problem:
Session session = this.sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Company.class);
criterion = Restrictions.eq("companyRoles.name", "ADMIN");
criteria.add(criterion);
List<Company> companyList = criteria.list();
Hibernate translates this to an SQL query (approximately)
SELECT *
FROM companies this_
inner join companyroles cr2_
ON this_.id = cr2_.companyid
inner join roles role1_
ON cr2_.rolename = role1_.NAME
WHERE role1_.NAME = 'ADMIN'
And now the problem: how can I reverse the query, i.e. find out all companies, which do not have a mapping for the role "ADMIN"? If I simply try to reverse the criterion by setting
criterion = Restrictions.ne("companyRoles.name", "ADMIN");
(not equals instead of equals), Hibernate creates a query like this
SELECT *
FROM companies this_
inner join companyroles cr2_
ON this_.id = cr2_.companyid
inner join roles role1_
ON cr2_.rolename = role1_.NAME
WHERE role1_.NAME != 'ADMIN'
Obviously, this does not produce the desired output, as the list still contains companies having the role "ADMIN", as long as the companies have at least one other role.
What I want to have is a list of companies, which do not have the role "ADMIN". As an additional restriction, this should be doable by just modifying the Criterion object, if possible (this is because the criterion is built automatically as part of an internal framework, and it is not possible to make larger changes there). The solution should also work, when the Criteria object contains other, additional criterions.
How is this doable, or is it?
You need a subquery (DetachedCriteria).
DetachedCriteria sub = DetachedCriteria.forClass(Company.class);
criterion = Restrictions.eq("companyRoles.name", "ADMIN");
sub.add(criterion);
sub.setProjection(Projections.property("id"));
Criteria criteria = session.createCriteria(Company.class);
criteria.add(Property.forName("id").notIn(sub));
List<Company> companyList = criteria.list();
Something like that should do it.