HQL Object Named Parameters - hql

I was wondering if it is possible to retrieve a specific column from an object named parameter in HQL.
Example
public class Product
{
private int id;
private Supplier supplier;
private String name;
private String description;
private double price;
public Product()
{
super();
}
public Product(String name, String description, double price)
{
super();
this.name = name;
this.description = description;
this.price = price;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Supplier getSupplier()
{
return supplier;
}
public void setSupplier(Supplier supplier)
{
this.supplier = supplier;
}
public double getPrice()
{
return price;
}
public void setPrice(double price)
{
this.price = price;
}
}
as you can see I created the product and it has a supplier object within it.
So when I do HQL and call
String hql = "from Product as product where product.supplier=:supplier";
Query query = session.createQuery(hql);
query.setEntity("supplier",supplier);
List results = query.list();
displayProductsList(results);
but is it possible to just get product's supplier's name?
and not just the whole supplier?

Just don't pass a Supplier instance to your query, but pass the supplier's name directly:
String hql = "from Product as product where product.supplier.name = :supplierName";
Query query = session.createQuery(hql);
query.setString("supplierName", supplier.getName());
List results = query.list();
displayProductsList(results);

Related

HashMap from nested objects

I am in need of help to create a hashmap.
public class Driver {
private String id;
private String name;
private List<Student> students;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
public class Student {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
There will be a List of Driver objects. Every Driver has List of Student objects. Could someone help me how to create this Map using streams: <Student.id, Driver.id>
Thanks!
You can use flatMap to build a Stream of all the (Student ID, Driver ID) pairs and then collect them into a Map:
List<Driver> drivers = new ArrayList<> ();
Map<String,String>
studentDrivers =
drivers.stream ()
.flatMap (drv -> drv.getStudents ()
.stream ()
.map (st -> new SimpleEntry<String,String> (st.getId (), drv.getId ())))
.collect (Collectors.toMap (Map.Entry::getKey,
Map.Entry::getValue));

org.neo4j.driver.v1.exceptions.ServiceUnavailableException: Connection to the database terminated

I want to connect Spring Boot with neo4j database, however, it returns an error like that. It says that the connection has been terminated. The error is as follow:
org.neo4j.driver.v1.exceptions.ServiceUnavailableException: Connection to the database terminated.
This is my Controller
#RequestMapping("/neo4j/Movie")
public class MovieController {
private final MovieRepository movieRepository;
public MovieController(MovieRepository movieRepository) {
this.movieRepository = movieRepository;
}
#GetMapping("/graph")
public List<Movie> graph() {
return (List<Movie>) movieRepository.findAll();
}
}
This is my Repository
#Repository
public interface MovieRepository extends Neo4jRepository<Movie,Long> {
#Query("MATCH(m:Movie)<-[relation:ActedIn]-(b:Actor) RETURN m,relation,b")
Collection<Movie> graph();
}
And the application.properties
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=neo4j
spring.data.neo4j.uri=bolt://localhost:7687
NodeEntity of moview
#NodeEntity
public class Movie {
#Id
private int id;
private String title;
private String genre;
// #JsonIgnoreProperties("movie")
#Relationship(type = "ActedIn")
private List<Actor> actors;
// #Relationship(type = "ACTED_IN" , direction = Relationship.INCOMING)
// private List<Actress> actresses = new ArrayList<>();
public Movie() {
}
public List<Actor> getActors() {
return actors;
}
public void setActors(List<Actor> actors) {
this.actors = actors;
}
public Movie(int id, String title, String genre, List<Actor> actors) {
this.id = id;
this.title = title;
this.genre=genre;
this.actors=actors;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre=genre;
}
}
And NodeEntity of Actor
public class Actor {
#GraphId
private Long id;
private String name;
private int age;
public Actor() {
}
public Actor(Long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I also tried springboot + neo4j projects downloaded from github, and also followed the instructions from neo4j website, but the projects still failed on my computer, so is there any super tutorials for neo4j and springboot?

How can I fetch data from 2 tables using HQL having one to many association with each other?

I have 2 tables in my database, city and hotel_details. Primary key of city is foreign key in hotel_details and associated with one to many association. I want to fetch data(status,registration,etc..) from hotel_details based on city_id and hotel_name by calling getAvailabilityStatus from my controller. Following is my code :
City Entity class
#Entity
#Table(name="city")
public class City {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="city_name")
private String cityName;
#OneToMany(mappedBy="city",
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
private List<HotelDetails> hotelDetails;
public City() {
}
public List<HotelDetails> getHotelDetails() {
return hotelDetails;
}
public void setHotelDetails(List<HotelDetails> hotelDetails) {
this.hotelDetails = hotelDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
#Override
public String toString() {
return "City [id=" + id + ", cityName=" + cityName + "]";
}
}
2.HotelDetails Entity class
#Entity
#Table(name="hotel_details")
public class HotelDetails {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#ManyToOne(cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
#JoinColumn(name="city_id")
private City city;
#Column(name="hotel_name")
private String hotelName;
#Column(name="available_date")
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date availableDate;
#Column(name="price")
private int price;
#Column(name="gst")
private int gst;
#Column(name="status")
private int status;
#Column(name="room_type")
private String roomType;
public HotelDetails() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public String getHotelName() {
return hotelName;
}
public void setHotelName(String hotelName) {
this.hotelName = hotelName;
}
public Date getAvailableDate() {
return availableDate;
}
public void setAvailableDate(Date availableDate) {
this.availableDate = availableDate;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getGst() {
return gst;
}
public void setGst(int gst) {
this.gst = gst;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getRoomType() {
return roomType;
}
public void setRoomType(String roomType) {
this.roomType = roomType;
}
#Override
public String toString() {
return "HotelDetails [id=" + id + ", hotelName=" + hotelName + ", availableDate=" + availableDate + ", price="
+ price + ", gst=" + gst + ", status=" + status + ", roomType=" + roomType + "]";
}
}
3.HotelDAOImpl
#Component
#Repository
public class HotelDetailsDAOImpl implements HotelDetailsDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public Set<String> getHotels() {
Session currentSession = sessionFactory.getCurrentSession();
Query theQuery2 = currentSession.createQuery("Select h.hotelName from HotelDetails h");
List<String> listHotels = theQuery2.list();
Set<String> hotels = new HashSet<String>(listHotels);
return hotels;
}
#Override
#Transactional
public List<City> getAvailabilityStatus(int cityID, String hotelName, String cityName) {
Session currentSession = sessionFactory.getCurrentSession();
Query theQuery4 = currentSession.createQuery("...");
//theQuery4.setParameter("hotelName", hotelName);
//List<City> cities = theQuery4.list();
return cities;
}
}
String jpql = "select c from City c join c.hotelDetails h where h.hotelName = :hotelName";
or
String jpql = "select c from HotelDetails h join h.city c where h.hotelName = :hotelName";
and then
Query theQuery4 = currentSession.createQuery(jpql);
theQuery4.setParameter("hotelName", hotelName);
List<City> cities = theQuery4.list();
This is just an example, but once you have defined the join and the entity aliases correctly, you can refer to entity attributes in the WHERE clause any way you prefer.
For example:
jpql += " AND c.id=:id AND h.price<:price AND h.availableDate BETWEEN :start AND :end";
same for the select clause, you can use all the combinations of:
"select c.cityName, h.status, ..."
"select c, h from ..."
Check the Hibernate ORM query for many examples of how you can use JPQL/HQL.

Null value in primary key of hibernate entity

I faced with problem of null value in PK.
Here's an entity:
#Entity
#Table(name="space")
public class Space implements Serializable {
#Id
#GeneratedValue
#Column(nullable = false, unique = true)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="user_id")
private UserAccount user;
private String name;
private String description;
private Date createdTime;
private Date modifiedTime;
#OneToMany(mappedBy="space")
private Set<SpaceAccess> spaceAccesses = new HashSet<>();
public Set<SpaceAccess> getSpaceAccesses() {
return spaceAccesses;
}
public void setSpaceAccesses(Set<SpaceAccess> spaceAccesses) {
this.spaceAccesses = spaceAccesses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Space() {}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public UserAccount getUser() {
return user;
}
public void setUser(UserAccount user) {
this.user = user;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
}
I wrote strategy to generate PK properly but I always get Null in id field when I create new instance of the Space:
Space space = new Space();
Here's content of the object:
What i should do to generate id of instance properly using hibernate/spring mechanisms?
application.properties:
spring.datasource.url="some_url"
spring.datasource.username=name
spring.datasource.password=password
spring.jpa.generate-ddl=true
P.S. I use spring-boot-starter-data-jpa with version: 2.3.4.RELEASE.
Use:
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

How to perform sql queries in jpa repository based on String parameter

I want to display table data based on different parameters like price range as well as category.
#Entity
public class Item {
#Id
#GeneratedValue
private Long id;
private String name;
private Double price;
private String category;
public Item() {
super();
}
Item(String name, String category){
super();
this.name = name;
this.category = category;
}
public Item(Long id, String name,Double price,String category) {
super();
this.id = id;
this.name = name;
this.price = price;
this.category=category;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
#Repository
public interface ItemRepository extends JpaRepository<Item, Long >{
}
I want to use postman to display table data based on category and price range.
Due to the usage of long as a parameter, I am only able to retrieve item based on id number.
From your question what i understood was that you need to have methods to return data based on Category and Price rather than using the id.
#Repository
public interface ItemRepository extends JpaRepository<Item, Long >{
List<Item> findByCategory(String category);
List<Item> findByPrice(Double price);
}
You can use the Spring JPA Query methods to have default implementations for that as well.
For more information read Official Doc.
Another Example:
List<Item> findByCategoryAndPrice(String category,Double price);

Resources