I have a category table that have its own unique id and name,
I have a product table that have its own unique id, name, price and categoryId.
Category.java
#Entity
public class Category {
#Id
#GeneratedValue
private long id;
private String name;
#OneToMany(fetch=FetchType.LAZY, mappedBy = "category")
private Set<Product> products;
//getters and setters
}
Product.java
#Entity
public class Product {
#Id
private long productId;
private String name;
private double price;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="categoryId")
private Category category;
public Product() {
}
public Product(long productId, String name, double price) {
super();
this.productId = productId;
this.name = name;
this.price = price;
}
public long getProductId() {
return productId;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
When I try to create a new product by post method, I should be able to read or write it's categoryId, but I can't. What am I doing it wrong?
You should not be able to write its categoryId, but you need a getter and a setter for Product.category. To change the category of a product, you would do product.setCategory(newCategory). If you want to READ the category ID of a product, you also need to add a getter for Category.id; you would then do: product.getCategory().getId().
Related
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String productName;
private int year;
private Double price;
private String url;
public Product() { }
public Product(String productName, int year, Double price, String url) {
this.productName = productName;
this.year = year;
this.price = price;
this.url = url;
}
}
I have a problem with my Springboot. Even when I add #Id, the log tells me that Product didn't have any Id.
Make sure you add your entity class in repository interface
eg:
public interface Repository extends JpaRepository<Product,Long>{
}
and in entity
change private int year
to
private Integer year
Thanks, everyone help me with this. I had already fixed this. The problem was IJ auto complete wrong import. In this case I have to use javax.persistence but IJ auto complete it to a org.springframework.data.id
I have an entity like this and when i want to create a new product i want to post also category of id that involves this product.
is any way ta access category by id ...i try to create a constructor to category with id as param but this does not solve my problem
#Entity
#Data
#Table(name="products")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="name")
private String name;
#Column(name="description")
private String description;
#Column(name="base64Image")
private String base64Image;
#Column(name="price")
private Double price;
#ManyToOne(fetch = FetchType.EAGER,cascade =CascadeType.ALL)
#JoinColumn(name = "category_id")
private Category category;
#ManyToOne
#JoinColumn(name="discount_id",referencedColumnName = "id")
private Discount discount;
#OneToMany(mappedBy = "product")
private Set<ProductLocation> productLocations;
#CreationTimestamp
#Column(name="created_at")
private LocalDateTime created_at;
#UpdateTimestamp
#Column(name="updated_at")
private LocalDateTime updated_at;
}
I have this dto but when using mapstruct category id of product created remains null`
#Data
public class ProductRequestDto {
private String name;
private String description;
private String base64Image;
private Double price;
private Long categoryId;
#JsonIgnore
private Discount discount=null;
}
the mapper interface that i have used
#Mapper(componentModel = "spring")
public interface ProductMapper {
ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);
List<ProductResponseDto> productToDto(List<Product> products);
Product dtoToProduct(ProductRequestDto product);
ProductResponseDto productToDto(Product product);
void update(#MappingTarget Product product, ProductRequestDto productDto);
}
can you suggest any solution
For me best option is to
change mapper to be abstract class instead interface adding annotation to it
#Mapper(componentModel = "spring")
adding #Mapping(target = "Category", source = "categoryId") to productToDto method
Autowiring categoryRepository to Mapper
and creating custom method for mapping from id to Entity
public Category resolveCategory(Long categoryId) {
if (categoryId == null) {
return null;
}
return categoryRepository.getById(categoryId);
}
I have a database with following tables -
My State Table
with columns - id and state
My City Table
with columns - id, city and state_id
And I want to get all the cities when i request get request with a particular state id to get its cities.
State Entity Class -
#Entity
#Table(name = "states")
public class State {
#Id
private int id;
private String state;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "state_id")
private List<City> cities = new ArrayList<>();
public State() {
}
public long getId() {
return id;
}
public String getState() {
return state;
}
}
City Entity Class -
#Entity
#Table(name = "cities")
public class City {
#Id
private long id;
private String city;
private int state_id;
public City() {
}
public long getId() {
return id;
}
public String getCity() {
return city;
}
public int getState_id() {
return state_id;
}
}
How can I get this to work ?
any help is appreciated.
I am learning jpa on my own by using online tutorials & trying out possible examples but now i am little confused about how to use relationships between tables. I have 3 classes having #Entity annotation which means jpa will create table based on these classes.i have id field in Student, Course, Booking classes and they will be primary key for respective tables.
The help i need is, in Booking class there is sid & cid fields and i want them to be referenced such as sid(Student.java)=sid(Booking.java) & cid(Course.java)=cid(Booking.java) and the scenario is each student can one or multiple bookings of one or multiple course. can someone tell me how & where should i use #OnetoOne, #OnetoMany, #ManytoMany, #ManytoOne in my code.
Student.java
package com.testapp;
import java.util.List;
import javax.persistence.*;
#Entity
public class Student{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int sid;
private String name;
private int salary;
//Getters and Setters....
..
public Student() {
super();
}
public Student(int sid, String name, float salary) {
super();
this.sid = sid;
this.name = name;
this.salary = salary;
}
public Student(String name, float salary) {
super();
this.name = name;
this.salary = salary;
}
}
Course.java
package com.testapp;
import java.util.List;
import javax.persistence.*;
#Entity
public class Course {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int cid;
private String cname;
private int price;
//Getters and Setters....
..
public Course() {
super();
}
public Course(int cid, String cname, int price) {
super();
this.cid = cid;
this.cname = cname;
this.price = price;
}
public Course(String cname, int price) {
super();
this.cname = cname;
this.price = price;
}
}
Booking.java
package com.testapp;
import java.util.Set;
import javax.persistence.*;
#Entity
public class Booking {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int bid;
private String date;
private int sid;
private int cid;
//Getters and Setters....
..
public Booking() {
super();
}
public Booking(int bid, String date, int sid, int cid) {
super();
this.bid = bid;
this.date= date;
this.sid = sid;
this.cid = cid;
}
public Booking(String date, int sid, int cid) {
super();
this.date = date;
this.sid = sid;
this.cid = cid;
}
}
Thank You..
Just define object in you class, as an example student involving many Cource , then you can define property on student class like below
public class Student{
private List<Cource> cources;
}
then orm detects the relationship, but also you have annotations like #OneToMant #ManyToMany in JPA
The best way to define this relationship in your case will be Student and Course will have OneToMany relation with Booking. And Booking will have ManyToOne relation with Student and Course
Student.java
#OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true)
public Set< Booking > getBookings() {
return bookings;
}
Course.java
#OneToMany(mappedBy = "course", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<Booking> getBookings() {
return bookings;
}
Booking.java
#Entity
public class Booking {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int bid;
private String date;
private Student student;
private Course course;
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "sid")
public Student getStudent() {
return student;
}
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "cid")
public Course getCourse() {
return course;
}
//Getters and Setters....
..
public Booking() {
super();
}
}
You should not use primary keys of other entities in JPA!
Use #ManyToOne and Student as well as Cource instead of sid and cid.
I am learning Hibernate, and I have a question about basic HQL join syntax. I am following this tutorial. Say I have a Product and Category entity,
#Entity
#Table(name = "CATEGORY")
public class Category {
private long id;
private String name;
private Set<Product> products;
public Category() {
}
public Category(String name) {
this.name = name;
}
#Id
#Column(name = "CATEGORY_ID")
#GeneratedValue
public long getId() {
return id;
}
#OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
public Set<Product> getProducts() {
return products;
}
// other getters and setters
}
#Entity
#Table(name = "PRODUCT")
public class Product {
private long id;
private String name;
private String description;
private float price;
private Category category;
public Product() {
}
public Product(String name, String description, float price,
Category category) {
this.name = name;
this.description = description;
this.price = price;
this.category = category;
}
#Id
#Column(name = "PRODUCT_ID")
#GeneratedValue
public long getId() {
return id;
}
#ManyToOne
#JoinColumn(name = "CATEGORY_ID")
public Category getCategory() {
return category;
}
// other getters and setters
}
So I have to join category and Product, I will something like this in sql
select * from Category A inner join Product B on A.id=B.category_id,
In HQL, it seems we drop the "on" condition, the HQL for the above query is
String hql = "from Product p inner join p.category";
Query query = session.createQuery(hql);
Why is on not required in HQL?
If you have an association (for an example #ManyToOne), you don't need on, Hibernate will add it to the SQL.
It was a problem prior to Hibernate 5.1, If you don't have an association. From Hibernate 5.1 you can use ad hoc joins:
How to join unrelated entities with JPA and Hibernate
Apart that, HQL also defines a with clause to qualify the join conditions:
Hibernate docs: Explicit joins