I am trying to do a hibernate join - the query seemingly works but when i try to cast from the object returned into the type i want it to be it doesnt work...im assuming because it has the joined table info too..
#Entity
#Table(name = "PSNG_SMRY")
public class PSNG_SMRY implements Serializable, Comparable<PSNG_SMRY>
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(generator="increment")
#GenericGenerator(name="increment" , strategy = "increment")
#Printable
public Integer SMRY_ID;
public Integer DEV_ID;
public Integer RPTD_TRN_ID;
#OneToOne(mappedBy="smry", cascade=CascadeType.ALL)
public TRN trn;
}
#Entity
#Table(name = "TRN")
public class TRN implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
public Integer TRN_ID;
public String TRN_SCTN
public String TRN_SYMB;
#OneToOne
#PrimaryKeyJoinColumn
private PSNG_SMRY smry;
}
I found this one to one mapping example here - link
And when I get the Object back from hibernate I try to cast it to PSNG_SMRY and it wont work - how am i am to do a join where i get the PSNG_SMRY info and the TRN_SYMB from the TRN table back using a join?
EDIT:
I get an invalid cast exception - [Ljava.lang.Object; cannot be cast to PSNG_SMRY
query code:
//code from some function that sets up all queries
String qQuery = "FROM PSNG_SMRY P, TRN T WHERE T.TRN_ID = P.RPTD_TRN_ID and P.FIR_AXLE_PASD_DT > sysdate - :timeLimit and P.FIR_AXLE_PASD_DT < sysdate - 1/24 ORDER BY P.FIR_AXLE_PASD_DT";
hqlParamList.add(new HQLParams("timeLimit", timeLimit)); //some list to pass to hibernate and then parameterize the queury
result = queryDatabase(qQuery, q4Query, hqlParamList);
public QueryResult queryDatabase(String qQuery, String q4Query,
List<HQLParams> params) {
QueryResult results = new QueryResult();
jwdsqa = new Connection("JWDSQA");
jwds4qa = new Connection("JWDS4QA");
results.qa = jwdsqa.retrieve(qQuery, params);
results.qa4 = jwds4qa.retrieve(q4Query, params);
return results;
}
EDIT:
This is the connection class - it is just used to get the session information and do all the hibernate stuff such as getting data...
public class Connection {
public static Logger logger = Logger.getLogger(Connection.class);
Session session;
String sessionName;
public Connection(String name){
session = HibernateUtil.getSessionFactory(name).openSession();
sessionName = name;
if(session.isConnected()){
//System.out.println(name + " - Connected");
}
}
public Session getSession(){
return session;
}
#SuppressWarnings("unchecked")
public List<Object> retrieve(String qry, List<HQLParams> paramList)
{
Transaction transaction = null;
List<Object> obj = null;
try {
transaction = session.beginTransaction();
String queryString = qry;
Query query = session.createQuery(queryString);
if(paramList != null)
{
for(HQLParams param: paramList)
{
query.setParameter(param.paramName, param.params);
}
}
List<Object> obj_ = query.list();
obj = obj_;
//session.getTransaction().commit();
} catch (HibernateException ex) {
ex.printStackTrace();
logger.error(ex.getMessage() + "\n" + ex.getStackTrace());
transaction.rollback();
} catch (Exception ex) {
System.err.println(ex.getMessage());
logger.error(ex.getMessage() + "\n" + ex.getStackTrace());
}
finally
{
session.close();
//System.out.println("Closing session " + sessionName);
}
return obj;
}
}
I ended up figuring this out - the reason why I was getting the casting error was hibernate was returning both the PSNG_SMRY and TRN objects back as an Object[] - and not as one Object.
If you want PSNG_SMRY instances you should not have to ask for the TRN table. This is provided for you when you use using JPA mapping
FROM PSNG_SMRY P
WHERE P.FIR_AXLE_PASD_DT > sysdate - :timeLimit
and P.FIR_AXLE_PASD_DT < sysdate - 1/24
ORDER BY P.FIR_AXLE_PASD_DT
If you do not get the TRN for the retrieved PSNG_SMRY objects then it means there is a mapping error because you are telling Hibernate how to retrieve the TRN for a PSNG_SMRY in your annotation
#OneToOne(mappedBy="smry", cascade=CascadeType.ALL)
public TRN trn;
Related
i am using Hibernate OGM (5.2.0.Alpha1) with Mongodb (3.6)
#Entity
#Table(name = "currency_master)
#JsonInclude(Include.NON_EMPTY)
public class CurrencyMaster{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonSerialize(using = ToStringSerializer.class)
#Column(name = "CURRENCY_ID", unique = true, nullable = false)
private ObjectId id;
private String code;
#OneToMany(mappedBy = "currencyMaster")
private Set<PurchaseOrder> setOfPurchaseOrder;
getter()
setter()
}
#Entity
#Table(name = "purchase_order)
#JsonInclude(Include.NON_EMPTY)
public class PurchaseOrder {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonSerialize(using = ToStringSerializer.class)
#Column(name = "PURCHASE_ORDER_ID", unique = true, nullable = false)
private ObjectId id;
private String purchaseOrderNo;
private Double total;
#ManyToOne
#JsonIgnore
private CurrencyMaster currencyMaster;
getter()
setter()
}
DAO Layer:
#SuppressWarnings("unchecked")
#Override
public <T> void update(T t) {
try {
Field[] fields = t.getClass().getDeclaredFields();
Map<String, Object> mapUpdatedFields = new HashMap<String, Object>();
for (Field field : fields) {
field.setAccessible(true);
mapUpdatedFields.put(field.getName(), field.get(t));
}
T newT = this.getById(mapUpdatedFields.get("id").toString(), t);
mapUpdatedFields.remove("id");
mapUpdatedFields.forEach((k, v) -> {
if (!AccountingMethodUtils.isObjectisNullOrEmpty("update()", v)) {
AccountingMethodUtils.setValueToField(newT, k, v);
}
});
entityManager.merge(newT);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(
"update() of DAO : (Error in outer try..catch) Error in updating record of {} and Error is {}.",
t.getClass(), e);
}
}
#Override
public <T> List<T> executeQuery(String query, Integer startPosition, Integer noOfRecords, T t) {
List<T> listOfT = new ArrayList<>();
if (AccountingMethodUtils.isObjectisNullOrEmpty(startPosition, noOfRecords)) {
listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).getResultList();
} else {
listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).setFirstResult(startPosition)
.setMaxResults(noOfRecords).getResultList();
}
return AccountingMethodUtils.isListIsNullOrEmpty(listOfT) ? new ArrayList<>() : listOfT;
}
Service Layer:
#Override
#Transactional
public String updatePurchaseOrder(AccountingRequestBody input) {
PurchaseOrder purchaseOrder = AccountingMethodUtils.getObjectMapper().convertValue(input.getJsonOfObject(),
PurchaseOrder.class);
// Query : db.purchase_order.find( {'_id' : ObjectId("5ab88323191bb91e78f9e33d") } , { 'purchaseOrderNo' : 1, 'currencyMaster_CURRENCY_ID' : 1 , 'total' : 1 })
StringBuilder sb = new StringBuilder().append("db.").append(AccountingVariableUtils.TABLE_NAME_FOR_PURCHASE_ORDER)
.append(".find( {'_id' : ObjectId('" + purchaseOrder.getId().toString()
+ "') } , { 'purchaseOrderNo' : 1, 'currencyMaster_CURRENCY_ID' : 1 , 'total' : 1 })");
List<PurchaseOrder> poFromDB = purchaseOrderDao.executeQuery(sb.toString(), null, null, new PurchaseOrder());
if (!AccountingMethodUtils.isListIsNullOrEmpty(poFromDB)) {
System.out.println("id before update : " + poFromDB.get(0).getCurrencyMaster().getId()); // Output: 5ab8830b191bb91e78f9e221
System.out.println("code before update : " + poFromDB.get(0).getCurrencyMaster().getCode()); // Output: INR
}
purchaseOrderDao.update(purchaseOrder);
poFromDB = purchaseOrderDao.executeQuery(sb.toString(), null, null, new PurchaseOrder());
if (!AccountingMethodUtils.isListIsNullOrEmpty(poFromDB)) {
System.out.println("id after update : " + poFromDB.get(0).getCurrencyMaster().getId()); // Output: 5ab8830b191bb91e78f9e221
System.out.println("code after update : " + poFromDB.get(0).getCurrencyMaster().getCode()); // Output: null //?????????????????????
}
}
output:
id before update : 5ab8830b191bb91e78f9e221
code before update: INR
id after update : 5ab8830b191bb91e78f9e221
code afterupdate: null ?????????????????????
Description:
Currency Master has one to many mapping(bidirectional) with purchase order.
In Service Layer,
first i executed query to get "id,code,total" from purchase order and successfully got all the fields.
then i updated purchase order.
then i again executed same query ( to get "id,code,total" from purchase order) after update then i can get id of currency master but can't get code of currency master.
Is Am i Right???
I think the problem is that you are using projection in your native query and trying to create the entity without retrieving all the information needed. I would remove the projection part from the native query and only use:
db.purchase_order.find( {'_id' : ObjectId("5ab88323191bb91e78f9e33d") } );
This happens because Hibernate OGM caches results, so you have to make sure to initialize entities correctly.
Or, even better, why don't you try using a JPQL query?
PurchaseOrder order = em.createQuery( "FROM PurchaseOrder po WHERE po.id = :id", PurchaseOrder.class )
.setParameter( "id", "5ab88323191bb91e78f9e33d" )
.getSingleResult();
By the way, Hibernate OGM shouldn't let you do this kind of things and will throw an exception in follow-up versions.
Last, I would recommend to update to Hibernate OGM 5.3.0.Final or at least to 5.2.0.Final (if there is any reason for you to stick to stick to the 5.2 family).
In My DaoImpl class I am trying to fetch list of data of Type TBatchEntry(model class)
#Override
public List<TBatchEntry> getBatchListFormQuery(String batchNo) {
session = sessionFactory.openSession();
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
try {
tx = session.beginTransaction();
batchListFromQuery = session.createSQLQuery("SELECT * FROM pghms.t_batchentry WHERE t_regNo LIKE '2008%'").list();
tx .commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
return batchListFromQuery;
}
In my Controller class I am trying to print value but it is throwing error in commented line:
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
try{
batchListFromQuery = adminService.getBatchListFormQuery(batchNo);
}catch(Exception e){
e.printStackTrace();
}
Iterator its = batchListFromQuery.iterator();
while(its.hasNext()){
batchFromQuery = (TBatchEntry) its.next(); //This line thorws error
System.out.println(batchFromQuery.getName());
}
This is my entity class
#Entity
#Table(name="t_batchEntry")
public class TBatchEntry {
#Id
#Column(name="t_regNo")
private String regNo;
#Column(name="t_name")
private String name;
public String getRegNo() {
return regNo;
}
public void setRegNo(String regNo) {
this.regNo = regNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
log of tomcat`root cause
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.sv.pghms.model.TBatchEntry
I'd be really thankful, if somebody could help me.
Try this way just change class name and where condition.It is working for me.
Hope so it will work for you.
List<Book> books = this.sf.getCurrentSession().createSQLQuery("select * from Book where book_id > 3")
.addEntity(Book.class)
.list();
for (Book book : books) {
System.out.println("Book Names are :: " + book.getBookName());
}
Why you are catching TBatchEntry into Object class.You can directly catch into TBatchEntry class.
Change Object[] into TBatchEntry Class, because you are selecting all columns from TBatchEntry table right, try below code i think it will work,
1) From Controller,
List batchListFromQuery = new ArrayList<>();
use foreach loop for displaying records
change return type as below :
#Override
public List<TBatchEntry> getBatchListFormQuery(String batchNo) {
session = sessionFactory.openSession();
List<TBatchEntry> batchListFromQuery = new ArrayList<>();
try {
tx = session.beginTransaction();
batchListFromQuery = session.createSQLQuery("SELECT * FROM pghms.t_batchentry WHERE t_regNo LIKE '2008%'").list();
tx .commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
return batchListFromQuery;
}
After some study I understood the difference between HQL & SQL query in hibernate.
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
In case of using HQL query:
batchListFromQuery = session.createQuery(sql).list()
In case of using SQL query:
batchListFromQuery = session.createSQLQuery(sql).addEntity(TBatchEntry.class).list();
Difference is:
.addEntity(TBatchEntry.class)
i'm on a final project now and making web app using hibernate.
my topic is recipe web site, and i have to show all the likers for a recipe
here's my pojo class for likes (not including the constructor and getter setter here to make it short code)
public class Likes implements java.io.Serializable {
private LikesId id;
private Member member;
private Resep resep;
private Integer likes;
public Likes() {
}
}
here's my pojo class for likes id (not including the getter setter here to make it short code)
public class LikesId implements java.io.Serializable {
private String idResep;
private String idMember;
public LikesId() {
}
public LikesId(String idResep, String idMember) {
this.idResep = idResep;
this.idMember = idMember;
}
}
now here is my method to show all likers for a recipe
public ArrayList<Likes> getAllLikes(String kode_resep)
{
this.session = NewHibernateUtil.getSessionFactory().openSession();
ArrayList<Likes> hasil = null;;
Transaction tx = session.beginTransaction();
Query q = session.createQuery("from Likes join LikesID on ()='"+kode_resep+"'");
hasil = (ArrayList<Likes>) q.list();
session.close();
return hasil;
}
the error when i run this method is:
Exception in thread "main"
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST
node: ( near line 1, column 35 [from model.Likes where
Likes.getId().getIdResep()='R001']
Try this:
Query q = session.createQuery("from Likes l where l.id.idResep = :code_resep");
q.setParameter("code_resep",kode_resep);
q.list();
Following are my code where I am fetching data from multiple table and want to print that data.
For fetching data I am using following method
public List<BillDetails> fetch(long id, long cid) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
List<BillDetails> obj = null;
try {
String hql = "select distinct bd,sum(bpds.amount) from BillDetails as bd "
+ "left join fetch bd.customerDetails as cd "
+ "left join fetch bd.billProductSet as bpd "
+ "left join fetch bpd.product as pd "
+ "left join fetch bd.billPaidDetails as bpds "
+ "where bd.billNo=:id "
+ "and bd.client.id=:cid ";
Query query = session.createQuery(hql);
query.setParameter("id", id);
query.setParameter("cid", cid);
obj = query.list();
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
e.printStackTrace();
tx.rollback();
}
} finally {
session.close();
}
System.out.println("Size is " + obj.size());
System.out.println(" " + obj.get(0).getBillNo());
return obj;
}
BillDetails pojo
public class BillDetails implements java.io.Serializable {
private Long billNo;
private CustomerDetails customerDetails;
private Client client;
private BigDecimal subTotal;
private BigDecimal vat;
private BigDecimal total;
private String invoiceNo;
private Date invoiceDate;
private String status;
private Timestamp addDate;
private Set<BillPaidDetails> billPaidDetails = new HashSet(0);
private Set<BillProduct> billProductSet = new HashSet(0);
//getter and setter
}
BillPaidDetails
public class BillPaidDetails implements java.io.Serializable {
private Long id;
private Client client;
private BillDetails billDetails;
private BigDecimal amount;
private String paymentMode;
private Date dt;
private Timestamp adddate;
}
While printing value at fetch() at System.out.println(" " + obj.get(0).getBillNo());
It is showing
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to iland.hbm.BillDetails.
How to resolve above exception and where the sum(bpds.amount) will store.
Is it possible that sum(bpds.amount) should be store in any desired fields of BillPaidDetails like added a field private BigDecimal totalAmount; where sum will stored.
First of all this query can't work as it is. I already responded about the need for including all fetched entities' properties in the group by clause.
You try to select both an entity and a sum, while expecting to fit into a List<BillDetails>.
If you were only selecting BillDetails you'd be fine. But when you want to select more than one entity you need to assign the select to a List<Object[]>:
List<Object[]> obj = null;
...
Object[] bdAndSum = obj.get(0);
BillDetails bd = (BillDetails) bdAndSum.get(0);
Number sum = (Number) bdAndSum.get(1);
Let's say I have entity A and entity B. Entity A have #OneTomany relationship with B.
I want to persist row in A only if it has one or more child object's associated with it else throw an exception.
How can i achieve the above requirement in hibernate
You neglected to mention what version of Hibernate you are using. In any case, this falls within the purview of validation. Luckily, in both Hibernate 3 and 4 you can utilize Hibernate Validator to do the job:
public class EntityB implements Serializable {
}
public class EntityA implements Serializable {
#NotNull
#Size(min = 1)
private Set<EntityB> relatedEntities;
}
You may need to pull in the Hibernate Validator jars into your project in order to be able to do this.
Entity class:Register.class
public class Register{
private Long regId;
#OneToMany(mappedBy = "reg")
private Set addrSet;
public Set getAddrSet() {
return addrSet;
}
public void setAddrSet(Set<Address> addrSet) {
this.addrSet = addrSet;
}
}
Entity Class:Address.java
public class Address{
object values;
#ManyToOne
private Register reg;
public Register getReg() {
return reg;
}
public void setReg(Register reg) {
this.reg = reg;
}
}
public void class searchObject(){
public List lst;
public register searchRegisterRow(Long regId){
Session session = null;
SessionFactory sessionFactory = null;
register result = null;
try{
sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
String SQL_QUERY ="from Register r where r.redId = "+regId;
Register reg = session.createQuery(SQL_QUERY);
for(Iterator it=lst.iterator();it.hasNext();){
reg=(Register)it.next();
if(reg.getAddrSet().size() > 0){
result = reg;
}
else{
throw new Exception();
}
}
return result;
}
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
// Actual contact insertion will happen at this step
session.flush();
session.close();
}
}
}
I think you should try above code. this will help you.