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 ?
Related
How can I create a Single Entity from two other tables/Entity in JPA/hibernate making a INNER JOIN result with a common key. I was using the below code but it gives me a full join instead of an inner join. it give me records from the meal table even if the
"id 1" does not exist in the allergies table, example:
{id=1, name='tacos', description='Mexican food', price ='10',peanuts=null, celery=null, sesameSeeds=null}
How can constrain to don't return any records if the 'id' is missing from the secondary table allergies? to show only records when the primary key is present in both tables.
I want something like this instead:
{id=1, name='tacos', description='Mexican food', price ='10',peanuts='no', celery='no', sesameSeeds='no'}
Please advise.
#Entity
#Table(name = "meal")
#SecondaryTable(name = "allergens", pkJoinColumns = #PrimaryKeyJoinColumn(name = "meal_id"))
class Meal {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
Long id;
#Column(name = "name")
String name;
#Column(name = "description")
String description;
#Column(name = "price")
BigDecimal price;
#Column(name = "peanuts", table = "allergens")
boolean peanuts;
#Column(name = "celery", table = "allergens")
boolean celery;
#Column(name = "sesame_seeds", table = "allergens")
boolean sesameSeeds;
// standard getters and setters
}
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
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;
}
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.
I have two classes:
#Entity
public class Tick {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne(optional = false)
#JoinColumn(name = "elitesystem_id", referencedColumnName = "id")
private EliteSystem eliteSystem;
private Date createDate;
#ManyToOne(optional = true)
#JoinColumn(name = "commander_id", referencedColumnName = "id")
private Commander commander;
private String address;
and
#Entity
public class Note {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne(optional = true)
#JoinColumn(name = "tick_id", referencedColumnName = "id")
private Tick tick;
private String text;
private Date createDate;
I want to select all ticks and get notes if there are any:
Query query = session.createQuery("select t, n from Note n right join n.tick t where t.commander.name = '123'");
List<Object[]> list = query.list();
This returns only Tick objects. What is the correct approach to get the Note information as well in 1 single query?
I could put a reference to a Note into the Tick class, but this doesnt sound right, as there are only a few notes, so the column in the Tick table would mostly be empty.
Create a New class for example:
public class TickNote {
private Tick tick;
private Note note;
public TickNote(Tick tick,Note note){
this.tick=tick;
this.note=note;
Then your query is:
Query query = session.createQuery("select NEW TickNote(t, n) from Note n right join n.tick t where t.commander.name = '123'");
List<TickNote> list = query.list();