Hibernate generates query without using where cluase - mysql

I use hibernate and MySQL.
I have a query in MySQL database which looks like:
select
phones0_.c_id as c_id_1, phones0_.cp_id as cp_id1_2, phones0_.cp_phone as cp_phon1
from
customer_phone phones0
where
phones0_.c_id in (select customer0_.c_id from customer customer0_ )
The issue is that there is no where clause in nested select. But I always use restrictions when i do some operations in JpaRepository.
I guess there are some issues in mapping.
Here are the examples of entities:
#Data
#Entity
class Customer {
#GeneratedValue
#Id
#Column(name="c_id")
Long id;
#Column(name="c_name")
private String name;
#OneToMany( mappedBy = "customer" )
#Fetch( FetchMode.SUBSELECT )
private List<CustomerPhone> phones;
}
#Data
#Entity
#Table(name = "customer_phone")
class CustomerPhone {
#GeneratedValue
#Id
#Column(name="cp_id")
Long id;
#Column(name="cp_phone")
private String phone;
#ManyToOne( fetch = FetchType.LAZY )
#JoinColumn( name = "id", nullable = false, updatable = false )
private Customer customer;
}

Related

Spring Data JPA - How to query table with no entity class?

I am working on below database tables :
users table - Each row represents a User in the system. It has a foreign key constraint to countries table.
countries table - Each row represents a Country and each country can have a list of dialects stored in table dialects.
I am using Spring data JPA and have created below entity classes
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "full_name")
private String fullName;
#Column(name = "createdAt")
private Date createdAt;
#Column(name = "country_code")
private Integer countryCode;
#Column(name = "dialect_key")
private String dialectKey;
}
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer country_code;
#Column(name = "name")
private String name;
#Column(name = "continent_name")
private String continentName;
#ElementCollection
#CollectionTable(name = "Dialect", joinColumns = { #JoinColumn(name = "country_code") })
private List<Dialect> dialectList;
}
#Embeddable
public class Dialect {
private String name;
}
Now I have a use case where I need to fetch the full name and dialect name for a given User.
Select u.full_name, d.name from users u
join countries c on u.country_code = c.country_code
join dialects d on c.country_code = d.country_code
where u.id = :user_id and u.dialect_key = d.dialect_key
Question - The above query works fine when ran as a native query and returns a List of Object. Further I am mapping the Objects List to the List of POJO. Is there a better way to do this to avoid Object -> POJO conversion explicitly ?

Failed to convert from type [java.lang.Object[]] to type [#org.springframework.data.jpa.repository.Query

I have spring boot project using JPA/Hibernate, MySQL. I have three dao classes that have a many to many relationship.
The Poko classes look like this
Product
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false, columnDefinition = "integer")
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "price")
private Double price;
#ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(
name = "product_extra",
joinColumns = #JoinColumn(name="product_id"),
inverseJoinColumns = #JoinColumn(name="extra_id")
)
private List<Extra> extras = new ArrayList<>();
//constructor getters and setters
}
ProductExtra
#Entity
#Table(name = "product_extra")
public class ProductExtra {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false, columnDefinition = "integer")
private Integer id;
#Column(name = "product_id")
private Integer productId;
#Column(name = "extra_id")
private Integer extraId;
//constructor getters and setter
}
Extra
#Entity
#Table(name = "extra")
public class Extra {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false, columnDefinition = "integer")
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "price")
private Double price;
#ManyToMany(mappedBy = "extras")
private List<Product> products = new ArrayList<>();
//constructor getters and setters
}
The Extra repository with the query
public interface ExtraRepository extends JpaRepository<Extra, Integer> {
#Query("SELECT e.id, e.name, e.price FROM Extra e INNER JOIN ProductExtra pe ON e.id = pe.extraId WHERE pe.productId = ?1")
List<Extra> findExtraById(Integer productId);
}
The mapping in my controller
#GetMapping("/product/{productId}")
public List<Extra>getExtraById(#PathVariable("productId") final Integer productId){
return extraRepository.findExtraById(productId);
}
I am trying to make a many to many query to select The extras in each product, i am however getting this error Failed to convert from type [java.lang.Object[]] to type [#org.springframework.data.jpa.repository.Query the error message surprisingly also contains the results i want. Not sure what am doing wrong
Remove the SELECT clause:
#Query("FROM Extra join e.productExtra WHERE pe.productId = ?1")
Also keep in mind, that you not write an SQL Query, You work on Object, so for join you use the mapped property

path expected for join JPA Hibernate MySQL

I'm using composite PK in my app with 2 tables and one joining table.
I wrote this query for function:
#Repository
public interface HospitalDoctorDao extends JpaRepository<HospitalDoctor, Integer>{
#Query("select hd from HospitalDoctor hd join hospital on hd.hospital_id=hospital.id join doctor on hd.doctor_id = doctor.id where hospital_id = ?1 and doctor_id = ?1")
HospitalDoctor findByHospitalIdAndDoctorId(int hospital_id, int doctor_id);
}
and I am getting error Path expected for file! In MySQL everything is working. How Hibernate works in this case? How I should write this query? Here is my #Entity of join table:
#Entity
#Table(name = "hospital_doctor")
public class HospitalDoctor {
#Embeddable
static class HosdocPK implements Serializable {
private int hospitalId;
private int doctorId;
}
#EmbeddedId
#JsonBackReference
public HosdocPK hosdocPK;
#JsonManagedReference
#MapsId("DoctorId")
#ManyToOne(optional = false)
#JoinColumn(name = "doctorId", referencedColumnName = "id")
private Doctor doctor;
#JsonManagedReference
#MapsId("HospitalId")
#ManyToOne(optional = false)
#JoinColumn(name = "hospitalId", referencedColumnName = "id")
private Hospital hospital;
#Column(name = "Id")
private int id;
#Temporal(TemporalType.DATE)
private Date contract_start_date;
#Temporal(TemporalType.DATE)
private Date contract_end_date;
private String position;
private String supervisor;
private boolean part_time;
Getters and setters
}
Your query is incorrect.
Try:
select hd from HospitalDoctor hd where hd.hospital.id = ?1 and hd.doctor.id = ?2

Alternative for #Formula?

I have two objects:
#Table(name = "user")
User
#Id
Integer id
Integer uuid;
and reservation:
#Table(name = "reservation")
Reservation
#Id
Integer id;
Integer uuid;
My goal is:
#Table(name = "reservation")
Reservation
#Id
Integer id;
Integer uuid;
#Formula("(SELECT * FROM user b WHERE b.uuid = uuid )")
List<User> users;
The problem is #Formula doesnt work with objects.
How to include list of all users in reservation with same uuid?
I found this but maybe there is better option
https://stackoverflow.com/a/37502703/3871754
Support of relationships that references non-PK columns is an optional feature. In simple cases it's supported by Hibernate
#NotAudited
#OneToMany
#JoinColumn(name = "uuid", referencedColumnName = "uuid")
private List<Barrier> barriers = new ArrayList<>();
and implemented Serializable for Reservation

Hibernate HQL query get data from table associated with another table

I have an entity called Locality as:-
#Entity
#Table(name = "CMN_LOCALITY_MASTER")
public class Locality {
#Id
#Column(name = "LOCALITY_ID", unique = true, nullable = false,length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
int localityId;
#Column(name = "LOCALITY_DESCRIPTION",length=70)
String localityDescription;
#JsonProperty(access = Access.WRITE_ONLY)
#ManyToOne
#JoinColumn(name = "PINCODE_ID")
Pincode pinCode;
#JsonIgnore
#ManyToOne
City city;
}
which contains another entity called City and Pincode.
City is as below:-
#Entity
#Table(name = "CMN_CITY_MASTER")
public class City{
#Id
#Column(name = "CITY_ID", unique = true, nullable = false,length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int cityId;
#Column(name = "CITY",length = 150)
private String description;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "STATE_ID")
private State state;
}
I want to Get all data from Locality entity/table which has City ID = (e.g. 1)
I tried below queries:-
#Query("SELECT a FROM Locality a INNER JOIN a.city c WHERE c.cityId=?1")
List<Locality>getAllLocalityByCity(int cityId);
and also
#Query("SELECT a FROM Locality a WHERE a.city.cityId=?1")
List<Locality>getAllLocalityByCity(int cityId);
But these are not working.
Could you please suggest me something/way to query the data?
Also, is there an Eclipse Plug-In/Tool to test HQL queries in a faster way than restarting the server for every change in the query?
Could you also suggest reading documents/book for learning HQL?
Since you are not providing any logs or explanation I can suggest you try the following:
#Query("SELECT a FROM Locality a INNER JOIN a.city c WHERE c.cityId = :cityId")
List<Locality>getAllLocalityByCity(#Param("cityId") int cityId);
For learning the HQL I would start with Hibernate Docs. You can take a look at Criteria API as well.