Querying with joined table id in JPA without NativeQuery - java

My object is
#Entity
public class DiscoveryResult {
.....
#ManyToOne
#JoinColumn
private Company company;
....
I want to querying like this;
#Query(value="SELECT scope from DiscoveryResult where company = :companyId group by scope")
List<String> findDistinctCategories(long companyId);
How can I query by id which under company

You need to join the DiscoveryResult and Company entities and then compare the id column of the Company with the companyId query parameter.
#Query(value="SELECT r.scope from DiscoveryResult r JOIN r.company c where c.id = :companyId group by scope")
List<String> findDistinctCategories(long companyId);

Related

Spring Data JPA: How to use DISTINCT with ORDER BY? [duplicate]

This question already has answers here:
MySQL: Select DISTINCT / UNIQUE, but return all columns?
(19 answers)
Closed 8 months ago.
I am running into
ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
Here are my Models & Query:
//Models:
#Entity
#Table(name = "Book")
#Data
public class Book {
#Id
private String id;
#OneToMany
private List<Category> category;
}
#Entity
#Table(name="Category")
#Data
public class Category {
#Id
private int id;
private String category;
}
//
#Repository
public interface BookDao extends JpaRepository<Book, Integer> {
#Query("SELECT DISTINCT b FROM Book b join b.category c order by c.id DESC")
Page<Book> getByBookIdDESC(Pageable pageable);
}
Things I've Tried: Providing b.category in the select.
#Query("SELECT DISTINCT b, c.id FROM Book b join b.category c order by c.id DESC")
Page<Book> getByBookIdDESC(Pageable pageable);
However, this is actually still providing duplicate results.
Book has one-to-many relation with category and it is possible that a book belong to multiple categories so it is expected having duplicate books in resultset.
Can you try with union ?
select distinct country
from (
select country, theOrderColumn from table1
union all
select country, theOrderColumn from table2
) a
order by theOrderColumn

How to select all fields of joined entities using hibernate?

I have two tables:
Limit_utilisation_history with fields:
bigint limit_utilisation_history_id (PK)
numeric(20,2) utilisation_amount
bigint limit_id (FK to limit_utilisation table)
Limit_utilisation with fields:
bigint limit_id (PK)
varchar customer_id
So both tables are related.
I need to expose the result of the following query via rest call:
select limit_utilisation_history_id, utilisation_amount, limit_id, customer_id
where customer_id in (some list of values)
I have done it in the following way:
#Entity
#Data
public class LimitUtilisation{
#Id
private Long limitIdl
private String customerId;
}
#Entity
#Data
#NamedQuery{
name = "LimitUtilisationHistory.getByCustomer",
query = "FROM LimitUtilisationHistory luh FETCH ALL PROPERTIES " +
"INNER JOIN luh.limitId al " +
"WHERE al.customerId in :values"
}
public class LimitUtilisationHistory{
#Id
private Long limitUtilisationHistoryId;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "limit_id", referencedColumnName = "limitId")
private LimitUtilisation limitId;
}
public interface LimitUtilisationHistoryRepository extends PagingAndSortingRepository<LimitUtilisationHistory, Long> {
#RestResource(path = "byCustomerId")
#Query
List<LimitUtilisationHistory> getByCustomer (#Param("values") List<String> customer);
}
It works fine, however when I call my rest endpoint I have only utilisation_amount value, others (mainly PK, FK, customer id are missing).
Does anyone have an idea how to do it correctly?
select limit_utilisation_history_id, utilisation_amount, limit_id, customer_id
where customer_id in (some list of values)
Remark: I cannot update DB structure. My intention is to only read from existing DB structure
As you you using FetchType.EAGER I don't see any reason of using FETCH ALL in the query, Could you please try with the below query :
select luh.limit_utilisation_history_id, luh.utilisation_amount, luh.limit_id, lu.customer_id
from LimitUtilisationHistory luh , LimitUtilisation lu
where luh.limit_id = lu.limit_id
and lu.customerId in :values

How do I access a many-to-many table in jpa?

This is the user class with a #manytomany mapping, I want it to be unidirectional.
#Entity
#Getter
#Setter
#Table(name="users")
public class User implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany
#JoinTable(name="user_drivers", joinColumns=#JoinColumn(name="user_id"), inverseJoinColumns=#JoinColumn(name="driver_id"))
private Set<Driver> driverSet;
public User() {
}
}
A table is created with both keys from user and driver, but I don't know how to access it within my repository.
#Query(value="select u.user_id from user_drivers")
List<?> findAllByIdAndDriver(Long id);
This gives an error: Can't resolve symbol 'user_drivers'
#Query(value="select id,driverSet from User ")
List<?> findAllByIdAndDriver(Long id);
And this results in a nester query exception.
Your method naming is confusing. When you say something like findByIdAndSomethingElse you're implying that you're doing this:
SELECT * FROM MY_TABLE WHERE ID = ? AND SOMETHING_ELSE = ?;
There's missing information here, since you don't share your complete repository or Driver implementations, but assuming you want all user IDs from a Driver with a specific ID, you can simply do this:
#Query("select driver.userId from Driver driver where driver.id = ?1")
public List<Long> findUserIdsByDriverId(long id);
The ?1 is the first argument. You can refer to subsequent arguments with ?2, ?3, ... , ?n
I think the correct queries should be like:
#Query(value="select u.userId from UserDrivers u")
and
#Query(value="select u.id, u.driverSet from User u")
For the 1st query, I'm assuming that entity for the other table is called UserDrivers and its column - userId (according to Java naming conventions).
Found what I needed thanks to the answers pointing me in the right direction.
#Query(value="select u.driverSet from User u where u.id=?1")
List<?> getDriverSet(Long id);

How to sort by pagerequest with inner join

I have two tables with many to one realtion. I want to sort data in table "user" by column "street" that is in "address" table in ASC or DESC direction defined by request param:
localhost:8080/getUsers?sort=address,desc
When I execute sql script:
SELECT * FROM user INNER JOIN address ON user.address_id=address.id ORDER BY street DESC
in workbench or phpMyAdmin it works good. All data are sorted by street name;
But when i try get it in postman by:
getUsers?sort=address,desc
I have this error in console output:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'INNER.address' in 'order clause'
Where is problem?
#Table(name = "user")
public class User {
private Long id;
private String name;
#ManyToOne()
#JoinColumn(name = "address_id")
private Address address;
}
#Table(name = "address")
public class Address {
private Long id;
private String street
#OneToMany(mappedBy = "address")
private List<User> user;
}
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "SELECT * FROM user INNER JOIN address ON user.address_id=address.id",
countQuery = "SELECT * FROM contact_messages INNER JOIN contact_topics ON contact_messages.contact_topic_id=contact_topics.id",
nativeQuery = true)
Page<User> findAll(Pageable pageable);
}
Also when i wrote query in repository like this it works as good as in workbench:
#Query(value = "SELECT * FROM user INNER JOIN address ON user.address_id=address.id ORDER BY address DESC",
countQuery = "SELECT * FROM contact_messages INNER JOIN contact_topics ON contact_messages.contact_topic_id=contact_topics.id ORDER BY address DESC",
nativeQuery = true)
But i want to have controll of request and sort data when i want (using sort param).
Try replacing the SQL to
SELECT u, a FROM user u INNER JOIN u.address a ORDER BY street DESC

Hibernate like query on Many-to-Many collection

I am having Userentity which has mapped to user_roles. I want to filter these roles based on User.idand roles.name
Same like as this SQL query
SELECT ur
FROM user
JOIN user_roles ur
ON ur.user_id = user.id
WHERE user.id = 1
AND ur.name like '%admin%';
How to achieve this SQL query in hibernate?
How to pass parameter to role name?
User.java
#Entity
class User {
#ManyToMany
#JoinTable(name="user_roles",
joinColumns=#JoinColumn(
name="user_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(
name="role_id", referencedColumnName="id")
)
public Set<Role> getRoles() {
return roles;
}
}
Hope it will help
select "your_req" from User us join usr.role usr where usr.name like '%admin%' and us.id=1
HQL supports exactly what you want, you can create an HQL query and then pass parameters to it. The following code block may be a reference:
Long userId = 1L;
String roleNamePattern = "%admin%";
Query query = session.createQuery("SELECT role FROM User user JOIN user.roles role WHERE user.id = :userid AND role.name LIKE :rolename");
query.setLong("userid", userId);
query.setString("rolename", roleNamePattern);
List<Role> roles = query.list();

Categories