The below query is working fine in mysql.
SELECT * FROM utilization u INNER JOIN sbg s on s.sbg_code=u.sbg_code where u.sbg_code=104
I have written below JPQL query.
#Query("SELECT i FROM Utilization i,i.sbg s where s.sbgCode = :sbgCode")
public ArrayList<Utilization> findUtilization(#Param("sbgCode") int sbgCode);
I am getting below error, please tell how to resolve this error
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: i.sbg is not mapped [SELECT i FROM be.g00glen00b.model.Utilization i,i.sbg s where s.sbgCode = :sbgCode]
Can you please tell me how to write the above sql query to JPQL query?
Please suggest some link to learn JPQL joins because I am new to this.
Below class represents the mapping between two tables
sbg class
#Entity
public class sbg {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int sbgCode;
private String sbgdesc;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="iccode")
#JsonIgnore
private Ic ic;
#OneToMany(mappedBy="sbg1", fetch=FetchType.EAGER)
private List<Utilization> utilization;
public int getSbgCode() {
return sbgCode;
}
public void setSbgCode(int sbgCode) {
this.sbgCode = sbgCode;
}
public String getSbgdesc() {
return sbgdesc;
}
public void setSbgdesc(String sbgdesc) {
this.sbgdesc = sbgdesc;
}
public Ic getIc() {
return ic;
}
public void setIc(Ic ic) {
this.ic = ic;
}
}
utilization class
package be.g00glen00b.model;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
public class Utilization {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int asset_type_key;
private String asset_type;
private String Engine_status;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "sbgCode")
private sbg sbg1;
public sbg getSbg1() {
return sbg1;
}
public void setSbg1(sbg sbg1) {
this.sbg1 = sbg1;
}
public int getAsset_type_key() {
return asset_type_key;
}
public void setAsset_type_key(int asset_type_key) {
this.asset_type_key = asset_type_key;
}
public String getAsset_type() {
return asset_type;
}
public void setAsset_type(String asset_type) {
this.asset_type = asset_type;
}
public String getEngine_status() {
return Engine_status;
}
public void setEngine_status(String engine_status) {
Engine_status = engine_status;
}
}
jpa repository
public interface UtilizationRepository extends JpaRepository<Utilization, Integer> {
#Query("SELECT i FROM Utilization i,i.sbg s where s.sbgCode = :sbgCode")
public ArrayList<Utilization> findUtilization(#Param("sbgCode") int sbgCode);
}
You are missing a JOIN in your query.
Your query should look like
SELECT i FROM Utilization i JOIN i.sbg s where s.sbgCode = :sbgCode
When you do queries like this you need to keep in mind that you might get duplicate results back. If you want to get unique results you should use a Set or have a look at this for a way to achieve it with hints and hibernate.
Related
I have modelled a car park with building and floor models. There is a one to many relationship between building and floor. I have built a rest controllers to retrieve the data. I am attempting to retrive the data via a simple get request to api/v1/parkingbuildings/1/. The issue is that when retrieving a building i do not see a list of floors as per my relation mapping. Any insight into any mistakes i may be making would be appreciated. Below is the json that gets returned;
{"building_id":1,"building_name":"Labadiestad","postcode":"SA78BQ","max_floors":14,"owner_name":"Schaefer, Gutmann and Braun"}
I am expecting to see a collection of floors in the payload and i cannot fathom why, ive written other similar simpler solutions that do the same without issue, ive compared my prior solutions and see little difference that matters in my approach.
Here is my building model
package com.admiral.reslink.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity(name = "parking_buildings")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class ParkingBuilding {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long building_id;
private String building_name;
private String postcode;
private int max_floors;
private String owner_name;
// ToDo sort the relationships
#OneToMany(mappedBy = "parkingBuilding")
#JsonIgnore
private List<ParkingFloor> parkingFloors;
public ParkingBuilding() {
}
public long getBuilding_id() {
return building_id;
}
public void setBuilding_id(long building_id) {
this.building_id = building_id;
}
public String getBuilding_name() {
return building_name;
}
public void setBuilding_name(String building_name) {
this.building_name = building_name;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public int getMax_floors() {
return max_floors;
}
public void setMax_floors(int max_floors) {
this.max_floors = max_floors;
}
public String getOwner_name() {
return owner_name;
}
public void setOwner_name(String owner_name) {
this.owner_name = owner_name;
}
public List<ParkingFloor> getParkingFloors() {
return parkingFloors;
}
public void setParkingFloors(List<ParkingFloor> parkingFloors) {
this.parkingFloors = parkingFloors;
}
}
And here is my floor model
package com.admiral.reslink.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name = "parking_floors")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class ParkingFloor {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long floor_id;
private int floor_number;
private int max_height_inches;
private boolean is_covered;
private boolean is_disabled_access;
// ToDo sort the relationships
#ManyToOne
#JoinColumn(name="building_id", nullable=false)
private ParkingBuilding parkingBuilding;
#OneToMany(mappedBy = "parkingFloor")
#JsonIgnore
private List<ParkingSpace> parkingSpace;
public ParkingFloor() {
}
public long getFloor_id() {
return floor_id;
}
public void setFloor_id(long floor_id) {
this.floor_id = floor_id;
}
public int getFloor_number() {
return floor_number;
}
public void setFloor_number(int floor_number) {
this.floor_number = floor_number;
}
public int getMax_height_inches() {
return max_height_inches;
}
public void setMax_height_inches(int max_height_inches) {
this.max_height_inches = max_height_inches;
}
public boolean isIs_covered() {
return is_covered;
}
public void setIs_covered(boolean is_covered) {
this.is_covered = is_covered;
}
public boolean isIs_disabled_access() {
return is_disabled_access;
}
public void setIs_disabled_access(boolean is_disabled_access) {
this.is_disabled_access = is_disabled_access;
}
public ParkingBuilding getParkingBuilding() {
return parkingBuilding;
}
public void setParkingBuilding(ParkingBuilding parkingBuilding) {
this.parkingBuilding = parkingBuilding;
}
public List<ParkingSpace> getParkingSpace() {
return parkingSpace;
}
public void setParkingSpace(List<ParkingSpace> parkingSpace) {
this.parkingSpace = parkingSpace;
}
}
Here is my building controller
package com.admiral.reslink.controllers;
import com.admiral.reslink.models.ParkingBuilding;
import com.admiral.reslink.models.ParkingFloor;
import com.admiral.reslink.repositories.ParkingBuildingRepository;
import com.admiral.reslink.repositories.ParkingFloorRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping("/api/v1/parkingbuildings")
public class ParkingBuildingController {
#Autowired
private ParkingBuildingRepository parkingBuildingRepository;
#GetMapping
public List<ParkingBuilding> list() {return parkingBuildingRepository.findAll();}
#GetMapping
#RequestMapping("{id}")
public ParkingBuilding get(#PathVariable Long id) {return parkingBuildingRepository.getById(id);}
#PostMapping
public ParkingBuilding create(#RequestBody final ParkingBuilding parkingBuilding) {
return parkingBuildingRepository.saveAndFlush(parkingBuilding);
}
#RequestMapping(value="{id}", method = RequestMethod.DELETE)
public void delete(#PathVariable Long id) {
parkingBuildingRepository.deleteById(id);
}
#RequestMapping(value="{id}", method = RequestMethod.PUT)
public ParkingBuilding update(#PathVariable Long id, #RequestBody ParkingBuilding parkingBuilding) {
ParkingBuilding existingParkingBuilding = parkingBuildingRepository.getById(id);
BeanUtils.copyProperties(parkingBuilding, existingParkingBuilding, "building_id");
return parkingBuildingRepository.saveAndFlush(existingParkingBuilding);
}
}
Not sure how you are retrieving the floors. OneToMany is by default lazy and would not load unless asked.
In your repository, try:
#EntityGraph(attributePaths = "parkingFloors")
ParkingBuilding findById(long id);
I have two entities called FeeTerms.java and FeeTermDates.java
I want to get all matched records from these two entities using pure HQL
Look at entities:
FeeTerms.java
package com.rasvek.cg.entity;
// Generated May 14, 2018 11:39:07 PM by Hibernate Tools 5.1.7.Final
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* FeeTerms generated by hbm2java
*/
#Entity
#Table(name = "fee_terms", catalog = "campus_guru_01")
public class FeeTerms implements java.io.Serializable {
private Integer termId;
private String termName;
private String termCount;
private Set<FeeTermDates> feeTermDateses = new HashSet<FeeTermDates>(0);
private Set<AssocFeeTerms> assocFeeTermses = new HashSet<AssocFeeTerms>(0);
public FeeTerms() {
}
public FeeTerms(String termName, String termCount, Set<FeeTermDates> feeTermDateses,
Set<AssocFeeTerms> assocFeeTermses) {
this.termName = termName;
this.termCount = termCount;
this.feeTermDateses = feeTermDateses;
this.assocFeeTermses = assocFeeTermses;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "term_id", unique = true, nullable = false)
public Integer getTermId() {
return this.termId;
}
public void setTermId(Integer termId) {
this.termId = termId;
}
#Column(name = "term_name")
public String getTermName() {
return this.termName;
}
public void setTermName(String termName) {
this.termName = termName;
}
#Column(name = "term_count", length = 45)
public String getTermCount() {
return this.termCount;
}
public void setTermCount(String termCount) {
this.termCount = termCount;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "feeTerms")
public Set<FeeTermDates> getFeeTermDateses() {
return this.feeTermDateses;
}
public void setFeeTermDateses(Set<FeeTermDates> feeTermDateses) {
this.feeTermDateses = feeTermDateses;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "feeTerms")
public Set<AssocFeeTerms> getAssocFeeTermses() {
return this.assocFeeTermses;
}
public void setAssocFeeTermses(Set<AssocFeeTerms> assocFeeTermses) {
this.assocFeeTermses = assocFeeTermses;
}
}
FeeTermDates.java
package com.rasvek.cg.entity;
// Generated May 14, 2018 11:39:07 PM by Hibernate Tools 5.1.7.Final
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* FeeTermDates generated by hbm2java
*/
#Entity
#Table(name = "fee_term_dates", catalog = "campus_guru_01")
public class FeeTermDates implements java.io.Serializable {
private int tdmId;
private FeeTerms feeTerms;
private String date;
public FeeTermDates() {
}
public FeeTermDates(int tdmId, FeeTerms feeTerms) {
this.tdmId = tdmId;
this.feeTerms = feeTerms;
}
public FeeTermDates(int tdmId, FeeTerms feeTerms, String date) {
this.tdmId = tdmId;
this.feeTerms = feeTerms;
this.date = date;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "tdm_id", unique = true, nullable = false)
public int getTdmId() {
return this.tdmId;
}
public void setTdmId(int tdmId) {
this.tdmId = tdmId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "term_id", nullable = false)
public FeeTerms getFeeTerms() {
return this.feeTerms;
}
public void setFeeTerms(FeeTerms feeTerms) {
this.feeTerms = feeTerms;
}
#Column(name = "date")
public String getDate() {
return this.date;
}
public void setDate(String date) {
this.date = date;
}
}
i have tried with following code but i am not getting it
String hql="select FT.termId , FT.termName , FT.termCount,FT.feeTermDateses from FeeTerms FT ,FeeTermDates FD where FT.termId=FD.feeTerms" ;
query = currentSession.createQuery(hql);
termDatesList= query.getResultList();
how to achieve it as pure HQL. i am very new to Hibernate and HQl.
i have got something like below in another post,
public List<Category> getCategoryList(int id) {
List<Category> groupList;
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("select c from Category c join fetch c.events where c.parentCategory.categoryId = 1");
//query.setParameter("id", id);
groupList = query.list();
return groupList;
}
Is it possible to achieve my query as above done?
You can receive a list of Object[] with the values that you want. Like:
String hql="select FT.termId , FT.termName , FT.termCount, FT.feeTermDateses from FeeTerms FT, FeeTermDates FD where FT.termId = FD.feeTerms.id";
Query query = currentSession.createQuery(hql);
List<Object[]> results = query.getResultList();
for (Object[] obj : results) {
Integer termId = obj[0];
String termName = obj[1];
String termCount = obj[2];
Set<FeeTermDates> feeTermDates = obj[4];
}
But, I could suggest a better version:
String hql = "SELECT ft FROM FeeTerms ft JOIN ft.feeTermDateses feeTermDateses";
Query query = currentSession.createQuery(hql);
List<FeeTerms> results = query.getResultList();
This already brings to you all FeeTerms that have FeeTermDates.
I am developing Spring Boot app with Spring Data JPA and H2 database. I was writing my model entity classes and I got to the moment where I need to make ManyToMany relationship between FreetimeActivity and Goal entities. In Goal class I have collection of Goalable objects. Goalable is my interface. This interface is implemented by 3 classes. I want objects of any of this classes to be stored in that collection. FreetimeActivity is one of them (but the only implemented so far). Can Spring Data make some magic and make that kind of relationship for me or do I have to make separate colletion for all of these 3 classes and merge them into one interface type collection in the end?
I tried with #ManyToMany and #JoinColumn annotations and added some testing code to starting class, but when run It throws an exception:
#OneToMany or #ManyToMany targeting an unmapped class: com.github.mesayah.assista.model.Goal.activityList[com.github.mesayah.assista.model.Goalable]
Are there any annotations that can make that for me?
FreetimeActivity.java
package com.github.mesayah.assista.model;
import javax.persistence.*;
import java.util.List;
/**
* Created by Mesayah on 03.07.2017.
*/
#Entity
#Table(name = "freetime_activity")
public class FreetimeActivity extends Activity {
#Id
#GeneratedValue
private long id;
private String name;
#ManyToMany(mappedBy = "freetime_activities")
private List<Goal> goals;
#Override
public long getId() {
return id;
}
#Override
public void setId(long id) {
this.id = id;
}
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
public List<Goal> getGoals() {
return goals;
}
public void setGoals(List<Goal> goalList) {
this.goals = goalList;
}
public FreetimeActivity(String name) {
this.name = name;
}
}
Goal.java
package com.github.mesayah.assista.model;
import javax.persistence.*;
import java.util.List;
/**
* Created by Mesayah on 02.07.2017.
*/
#Entity
public class Goal {
#Id
#GeneratedValue
private long id;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "goal_freetime_activity", joinColumns = #JoinColumn(name = "goal_id", referencedColumnName =
"id"),
inverseJoinColumns = #JoinColumn(name = "freetime_activity_id", referencedColumnName = "id"))
private List<FreetimeActivity> activityList;
private List<Milestone> milestoneList;
public Goal() {
}
public Goal(List<FreetimeActivity> activityList) {
this.activityList = activityList;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public List<FreetimeActivity> getActivityList() {
return activityList;
}
public void setActivityList(List<FreetimeActivity> activityList) {
this.activityList = activityList;
}
public List<Milestone> getMilestoneList() {
return milestoneList;
}
public void setMilestoneList(List<Milestone> milestoneList) {
this.milestoneList = milestoneList;
}
}
AssistaApplication.java
package com.github.mesayah.assista;
import com.github.mesayah.assista.model.Course;
import com.github.mesayah.assista.model.Exam;
import com.github.mesayah.assista.repository.CourseRepository;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.util.List;
#SpringBootApplication
#EnableJpaRepositories("com.github.mesayah.assista.model")
public class AssistaApplication {
private final static Logger logger = LoggerFactory.getLogger(AssistaApplication.class);
public static void main(String[] args) {
SpringApplication.run(AssistaApplication.class, args);
}
#Bean
#Transactional
public CommandLineRunner commandLineRunner(CourseRepository courseRepository, ExamRepository examRepository) {
return (args) -> {
Course course = new Course("Dancing Course");
Exam exam = new Exam("Dancing Test", course);
// testing save
courseRepository.save(course);
examRepository.save(exam);
course.getGrades().add(4.0);
course.getGrades().add(4.5d);
course.getGrades().add(3.5d);
// testing update
courseRepository.save(course);
// using Spring Data JPA automated repositories
List<Course> courses = (List<Course>) courseRepository.findAll();
List<Exam> result = examRepository.findByCourse(course);
Exam theExam = result.get(0);
// testing relations
logger.info("Courses in database: " + courses.size() + "\nExam's Course Id: " + theExam.getCourse().getId() + "\nCourse grades: " + theExam.getCourse().getGrades());
};
}
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
}
}
These are my pojo class
Orderdetail.java
package online.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "orderdetail")
public class OrderDetail {
#Id
#Column(name="order_detail_id")
private int order_detail_id;
#Column(name="bill")
private float bill;
#ManyToOne
#JoinColumn(name = "p_id" )
private Product p_id;
#ManyToOne
#JoinColumn(name = "o_id" )
private Order o_id;
public int getOrder_detail_id() {
return order_detail_id;
}
public void setOrder_detail_id(int order_detail_id) {
this.order_detail_id = order_detail_id;
}
public float getBill() {
return bill;
}
public void setBill(float bill) {
this.bill = bill;
}
public Product getP_id() {
return p_id;
}
public void setP_id(Product p_id) {
this.p_id = p_id;
}
public Order getO_id() {
return o_id;
}
public void setO_id(Order o_id) {
this.o_id = o_id;
}
}
My Order.java
package online.model;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name = "ordertable")
public class Order {
#Id
#Column(name = "order_id")
private int order_id;
#OneToMany(mappedBy = "o_id",cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderDetail> orderdetail;
#ManyToOne
#JoinColumn(name = "u_id")
private UserDetail u_id;
public UserDetail getU_id() {
return u_id;
}
public void setU_id(UserDetail u_id) {
this.u_id = u_id;
}
#Column(name = "date")
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#Column(name = "totalbill")
private Float totalbill;
public Float getTotalbill() {
return totalbill;
}
public void setTotalbill(Float totalbill) {
this.totalbill = totalbill;
}
public List<OrderDetail> getOrderdetail() {
return orderdetail;
}
public void setOrderdetail(List<OrderDetail> orderdetail) {
this.orderdetail = orderdetail;
}
public int getOrder_id() {
return order_id;
}
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
When ever I am trying to save order class I want my orderdetail class also get saved but when I am trying to save the List in order,Is is not getting saved and there is not error provided by hibernate that can help...
Thanks for the help
when i am trying to to persist the order class
Hibernate: select orderdetai_.order_detail_id, orderdetai_.bill as bill7_, orderdetai_.o_id as o3_7_, orderdetai_.p_id as p4_7_ from orderdetail orderdetai_ where orderdetai_.order_detail_id=?
This what I am getting output.
This is my code which save the class
#Override
public boolean payment(String username, Integer ordernumber, Date date,
Float totalbill, List<Integer> list) {
Session session = sessionFactory.openSession();
Transaction tranction = session.beginTransaction();
try {
Query query = session
.createQuery("from UserDetail where user_username = :username");
query.setParameter("username", username);
List<UserDetail> userdetaillist = query.list();
UserDetail userdetail = userdetaillist.get(0);
query = session
.createQuery("from ProductDetail where product_detail_id in(:list)");
query.setParameterList("list", list);
List<ProductDetail> productdetail = query.list();
Order order = new Order();
order.setOrder_id(ordernumber);
order.setDate(date);
order.setU_id(userdetail);
order.setTotalbill(totalbill);
List<OrderDetail> orderdetail = new ArrayList<OrderDetail>();
OrderDetail ordetail = new OrderDetail();
for (ProductDetail pro : productdetail) {
ordetail.setO_id(order);
ordetail.setP_id(pro.getProduct_id());
ordetail.setBill(pro.getProduct_id().getProduct_sell_price());
orderdetail.add(ordetail);
}
System.out.print("totalbill" + totalbill);
System.out.println(orderdetail);
order.setOrderdetail(orderdetail);
session.save(order);
tranction.commit();
return true;
} catch (Exception e) {
tranction.rollback();
e.getStackTrace();
}
return false;
}
I think ordetail has to be created inside the for.. You are modifying the same object for each productdetail. Should be like this:
List<OrderDetail> orderdetail = new ArrayList<OrderDetail>();
OrderDetail ordetail = null;
for (ProductDetail pro : productdetail) {
ordetail = new OrderDetail();
ordetail.setO_id(order);
ordetail.setP_id(pro.getProduct_id());
ordetail.setBill(pro.getProduct_id().getProduct_sell_price());
orderdetail.add(ordetail);
}
Hey I have recheck my pojo class and I found out the mistake I have done. I have made change and it work properly now.
I was not setting the the id for Orderdetail table. It was auto increment in database.
So it was giving me error ""
So I have made change in orderdetail iD
"#GeneratedValue(strategy=GenerationType.AUTO)" So now It is working fine cause now hibernate know that the id will get value from database.
Thanks for the help and for your time
I've got a #ViewScoped bean that calls a #Stateless bean which does a simple query to return some values from my DB.
This should be enough to make the query everytime I load the page, and this should lead me to have always updated data on each page load.
But this won't work, and I don't know how to solve it!
My query returns the old value, even after changing it with MySql Workbench.
(Doing the query on Workbench returns correct data!)
Here's the code :
DispensaListBean.java
package ManagedBeans;
import ejb.DispensaManager;
import ejb.DispensaManagerLocal;
import entity.Dispensa;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
/**
*
* #author stefano
*/
#ManagedBean
#ViewScoped
public class DispensaListBean {
#EJB
private DispensaManagerLocal dispensaManager;
/**
* Creates a new instance of DIspensaListBean
*/
public DispensaListBean() {
}
public List<Dispensa> getTopDispense(){
List<Dispensa> l = dispensaManager.findByVoto(DispensaManager.DESC);
for(Dispensa d : l){
System.out.println(d.getTitolo() + " | " + d.getVoto()); //This code prints ALWAY the old getVoto() value, it takes the new one just after restarting the server
}
return l;
}
public List<Dispensa> getDispense(){
return dispensaManager.findAll();
}
public Dispensa getById(int i){
return dispensaManager.findById(i);
}
}
DispensaManager.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ejb;
import entity.Dispensa;
import facade.DispensaFacadeLocal;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
/**
*
* #author stefano
*/
#Stateless
public class DispensaManager implements DispensaManagerLocal {
public static final int ASC=0, DESC=1;
#EJB
private DispensaFacadeLocal dispensaFacade;
#Override
public java.util.List<Dispensa> findByVoto(int order) {
return (order==DispensaManager.ASC) ? dispensaFacade.findByVotoAsc() : dispensaFacade.findByVotoDesc();
}
#Override
public List findAll() {
return dispensaFacade.findAll();
}
#Override
public Dispensa findById(int id) {
return dispensaFacade.find(id);
}
}
DispensaFacade.java
package facade;
import entity.Dispensa;
import entity.Post;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
*
* #author stefano
*/
#Stateless
public class DispensaFacade extends AbstractFacade<Dispensa> implements DispensaFacadeLocal {
#PersistenceContext(unitName = "UNILIFE-ejbPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public DispensaFacade() {
super(Dispensa.class);
}
#Override
public List<Dispensa> findByVotoDesc() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Dispensa> q = cb.createQuery(Dispensa.class);
Root<Dispensa> c = q.from(Dispensa.class);
q.select(c);
q.where(cb.isNotNull(c.get("datiFile")));
q.orderBy(cb.desc(c.get("voto")));
TypedQuery<Dispensa> typedQuery = em.createQuery(q);
return typedQuery.getResultList();
}
#Override
public java.util.List<Dispensa> findByVotoAsc() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Dispensa> q = cb.createQuery(Dispensa.class);
Root<Dispensa> c = q.from(Dispensa.class);
q.select(c);
q.where(cb.isNotNull(c.get("datiFile")));
q.orderBy(cb.asc(c.get("voto")));
TypedQuery<Dispensa> typedQuery = em.createQuery(q);
return typedQuery.getResultList();
}
}
Dispensa.java
package entity;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author stefano
*/
#Entity
#Table(name = "Dispensa")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Dispensa.findAll", query = "SELECT d FROM Dispensa d"),
#NamedQuery(name = "Dispensa.findById", query = "SELECT d FROM Dispensa d WHERE d.id = :id"),
#NamedQuery(name = "Dispensa.findByTitolo", query = "SELECT d FROM Dispensa d WHERE d.titolo = :titolo"),
#NamedQuery(name = "Dispensa.findByDescrizione", query = "SELECT d FROM Dispensa d WHERE d.descrizione = :descrizione"),
#NamedQuery(name = "Dispensa.findByTag", query = "SELECT d FROM Dispensa d WHERE d.tag = :tag"),
#NamedQuery(name = "Dispensa.findByData", query = "SELECT d FROM Dispensa d WHERE d.data = :data"),
#NamedQuery(name = "Dispensa.findByVoto", query = "SELECT d FROM Dispensa d WHERE d.voto = :voto"),
#NamedQuery(name = "Dispensa.findByNumVoti", query = "SELECT d FROM Dispensa d WHERE d.numVoti = :numVoti"),
#NamedQuery(name = "Dispensa.findByNumDownloads", query = "SELECT d FROM Dispensa d WHERE d.numDownloads = :numDownloads")})
public class Dispensa implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "titolo")
private String titolo;
#Size(max = 255)
#Column(name = "descrizione")
private String descrizione;
#Size(max = 255)
#Column(name = "tag")
private String tag;
#Basic(optional = true)
#NotNull
#Lob
#Column(name = "datiFile")
private byte[] datiFile;
#Basic(optional = false)
#NotNull
#Column(name = "data")
#Temporal(TemporalType.DATE)
private Date data;
#Basic(optional = false)
#NotNull
#Column(name = "voto")
private int voto;
#Basic(optional = false)
#NotNull
#Column(name = "numVoti")
private int numVoti;
#Basic(optional = false)
#NotNull
#Column(name = "numDownloads")
private int numDownloads;
#JoinTable(name = "Scaricati", joinColumns = {
#JoinColumn(name = "dispensa", referencedColumnName = "id")}, inverseJoinColumns = {
#JoinColumn(name = "utente", referencedColumnName = "username")})
#ManyToMany(fetch = FetchType.LAZY)
private Collection<Utente> downloaders;
#JoinColumn(name = "materia", referencedColumnName = "id")
#ManyToOne(optional = true)
private Materia materia;
#JoinColumn(name = "autore", referencedColumnName = "username")
#ManyToOne(optional = false)
private Utente autore;
public Dispensa() {
}
public Dispensa(Integer id) {
this.id = id;
}
public Dispensa(Integer id, String titolo, byte[] datiFile, Date data, int voto, int numVoti, int numDownloads) {
this.id = id;
this.titolo = titolo;
this.datiFile = datiFile;
this.data = data;
this.voto = voto;
this.numVoti = numVoti;
this.numDownloads = numDownloads;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitolo() {
return titolo;
}
public void setTitolo(String titolo) {
this.titolo = titolo;
}
public String getDescrizione() {
return descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public byte[] getDatiFile() {
return datiFile;
}
public void setDatiFile(byte[] datiFile) {
this.datiFile = datiFile;
}
public Date getData() {
return data;
}
public void setData(Date data) {
this.data = data;
}
public int getVoto() {
return voto;
}
public void setVoto(int voto) {
this.voto = voto;
}
public int getNumVoti() {
return numVoti;
}
public void setNumVoti(int numVoti) {
this.numVoti = numVoti;
}
public int getNumDownloads() {
return numDownloads;
}
public void setNumDownloads(int numDownloads) {
this.numDownloads = numDownloads;
}
#XmlTransient
public Collection<Utente> getDownloaders() {
return downloaders;
}
public void setDownloaders(Collection<Utente> utenteCollection) {
this.downloaders = utenteCollection;
}
public Materia getMateria() {
return materia;
}
public void setMateria(Materia materia) {
this.materia = materia;
}
public Utente getAutore() {
return autore;
}
public void setAutore(Utente autore) {
this.autore = autore;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Dispensa)) {
return false;
}
Dispensa other = (Dispensa) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.Dispensa[ id=" + id + " ]";
}
}
Now, I've faced this problem before with other entities and methods, and I solved it by refreshing the entities, but why should I refresh an entity in this case if I get it from the database everytime that I load the page?
It's just nonsense!
From the code itself it doesn't look like you're doing any explicit caching yourself. #ViewScoped, #RequestScoped and isPostback are all not relevant here, and on the contrary, the purpose of those scopes is actually to do caching, instead of letting the backing bean call through to the service each and every time.
That however is almost the opposite of your problem.
In case you get stale entities from the entity manager, it's almost always a case of an L2 cache. Did you configure any in persistence.xml? Which JPA implementation do you use?
Also important, where and how do you update your data? The code as given doesn't show it. You do mention this "even after changing it with MySql Workbench"
In the case that a JPA Level 2 (L2) cache is used, JPA will get the entities from this cache. Without counter measures, it will track changes to those entities only if they are modified via JPA. If you update the underlying data yourself, either directly via JDBC or via some other external system (like MySql Workbench), JPA will not be aware of those changes.
My instinct is that you have a stale cache of some sort.
Have you read this article?
I would first focus on your Session Bean. Create a test harness without the extra complexity of JSF pages.
I was expecting the default transaction behaviour of your Stateless bean to be "sensible", but I'm now wondering whether using
#TransactionAttribute(TransactionAttributeType.REQUIRED)
might solve your problem.
Most probably this is caused by MySQL's default isolation level which is REPEATABLE READ.
This means that you don't see changes done by other transactions until you end (commit, rollback) your "own" transaction (remember: a SELECT already starts a transaction)
I assume the EJB connection is taken from a connection pool and thus the transactions that are started are never ended properly. Try issuing a commit or rollback before running the select from within your web application.
For a permanent solution you can either change the default isolation by configuring your connection pool (most of them allow this), change the transaction level by calling setTransactionIsolation() on the connection or by changing the default isolation level in MySQL.
Are you using hibernate as your EntityManager? If so, it might be using the Session cache, and storing your object. In which case, if you change the data either through SQL or through a different session, you might need to call "refresh" on your object in order to pick up the changes.
Have you tried to change your bean to #RequestScoped ?
You need know if your page is a postback, http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/javax/faces/render/ResponseStateManager.html
Something like that
ResponseStateManager rsm = FacesContext.getCurrentInstance().getRenderKit().getResponseStateManager();
if (!rsm.isPostback(FacesContext.getCurrentInstance())) {
//do some stuff
}