I was trying to fetch hql query result assigned to custom class by casting the Object reference. but it throws for exception. But i have seen developers casting object reference returned from query to custom class reference without any issues.
What i wanted is,
//Address class
package car;
public class Address {
private int addId;
private String city;
private String country;
public String getCity() {
return city;
}
public int getAddId() {
return addId;
}
public void setAddId(int addId) {
this.addId = addId;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
//Hibernate mapping
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "car.Address" table = "studentAddress">
<id name = "addId">
<generator class = "assigned"/>
</id>
<property name = "city" column = "city"/>
<property name = "country" column = "country" />
</class>
</hibernate-mapping>
//Test class
public class Main {
public static void main(String[] args) {
Configuration cfg = new Configuration();
cfg.configure("retail\\resources\\hibernate.cfg.xml");
SessionFactory s = cfg.buildSessionFactory();
Session ss = s.openSession();
Transaction t = ss.beginTransaction();
Student stu = new Student();
stu.setSid(11);
stu.setName("Thanweer");
stu.setAge(28);
Address a = new Address();
a.setAddId(22);
a.setCity("Colombo");
a.setCountry("Sri Lanka");
Query q = ss.createQuery("select city,country from Address a where a.city = 'Colombo'" );
Address a2 = (Address)q.uniqueResult();
System.out.println(a2.getAddId()+" "+a2.getCity()+" "+a2.getCountry());
}
}
Exception Occurs is :
INFO: HHH000232: Schema update complete
Hibernate: select address0_.city as col_0_0_, address0_.country as col_1_0_ from studentAddress address0_ where address0_.city='Colombo'
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to car.Address
at test.Main.main(Main.java:36)
Following HQL
select city,country from Address a where a.city = 'Colombo'
selects List of Object arrays. Thats why [Ljava.lang.Object;For further details please refer to this question.
In each array index 0 contains String city and index 1 contains String country. With uniqueResult() result is no more list, but simply array of objects. When Address is preferred, one should select Address as follows:
Query q = ss.createQuery("select a from Address a where a.city = 'Colombo'" );
Address a2 = (Address)q.uniqueResult();
Related
I am trying to update a row by using its primary key, the issue is that Hibernate updates entire row and since I have not passed values for any other attributes (For Ex : Attributes are empid, name salary and address. I will pass empid=1 and name to be updated. But it will set NULL to other 2 values i.e. address and salary) it assigns NULL to them. I want to Update only selective attributes;
I tried using saveOrUpdate but that too is either entering new or updating same row with NULL values. Is there any other solutions???
Edit :
The below code are written in "Java Project" and not "Maven Project".
The files "MainExecute.java" and "employee.java" are in package "Lab3"
The files "employee.hbm.xml" and "hibernate.cfg.xml" are in the "src" Folder of the same Project.
Here are the codes
MainExecute.java
package Lab3;
import java.util.*;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class MainExecute {
SessionFactory sc = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
public void insert(int empid,String name,int salary,String address) {
Session session = sc.openSession();
Transaction t = session.beginTransaction();
employee e1=new employee();
e1.setEmpid(empid);
e1.setName(name);
e1.setSalary(salary);
e1.setAddress(address);
session.save(e1);
t.commit();
System.out.print("Entered Succesfully");
}
public void update(int empid,String name) {
Session session = sc.openSession();
Transaction t = session.beginTransaction();
Query q = session.createQuery("from employee");
List<?> l = q.getResultList();
Iterator<?> it = l.iterator();
employee e1 = (employee) it.next();
String Address;
int Salary;
//Saved the attributes that exist so that i can bypass the NULL assignment
Salary=e1.getSalary();
Address=e1.getAddress().toString();
//Detached the object from the session else it creates error,
//since hibernate cannot push parallel transaction on same reference objects
session.evict(e1);
employee e2=new employee();
//Setting the attributes that you want to update and rest with already backed up values from attribute
e2.setEmpid(empid);
e2.setName(name);
e2.setAddress(Address);
e2.setSalary(Salary);;
session.saveOrUpdate(e2);
t.commit();
}
public void delete(int empid) {
Session session = sc.openSession();
Transaction t = session.beginTransaction();
employee e1=new employee();
e1.setEmpid(empid);
session.delete(e1);
t.commit();
}
public void display() {
Session session = sc.openSession();
Transaction t = session.beginTransaction();
Query q = session.createQuery("from employee");
List<?> l = q.getResultList();
Iterator<?> it = l.iterator();
if(!it.hasNext()) {
System.out.println("\n\nNo Employees!!!\n");
}
while (it.hasNext()) {
employee e1 = (employee) it.next();
System.out.println("\nEmp ID :"+e1.getEmpid()+
"\t\tName :"+e1.getName()+
"\nSalary :"+e1.getSalary()+
"\t\tAddress :"+e1.getAddress());
}
t.commit();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MainExecute m1=new MainExecute();
Scanner sc=new Scanner(System.in);
int empid,salary,ch=0;
String name,address;
while(true) {
System.out.println("\n\n1.Insert\t2.Update\n3.Delete\t4.Display\nPress 0 to exit\n");
ch=sc.nextInt();
if(ch==1) {
System.out.println("Emp ID :");
empid=sc.nextInt();
System.out.println("Name :");
name=sc.next();
System.out.println("Salary :");
salary=sc.nextInt();
System.out.println("Address :");
address=sc.next();
m1.insert(empid, name, salary, address);
}else
if(ch==2) {
System.out.println("Emp ID :");
empid=sc.nextInt();
System.out.println("Name :");
name=sc.next();
m1.update(empid, name);
}else
if(ch==3) {
System.out.println("Emp ID :");
empid=sc.nextInt();
m1.delete(empid);
}else
if(ch==4) {
m1.display();
}else
if(ch==0) {
break;
}
}
}
}
employee.java
package Lab3;
//Persistence Class
import javax.persistence.*;
#Entity
#Table(name="employee")
public class employee {
#Id
int empid;
int salary;
String name,address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getEmpid() {
return empid;
}
public void setEmpid(int empid) {
this.empid = empid;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
employee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
<class name="Lab3.employee" table="employee">
<id name="empid" type="int" column="empid"></id>
<property name="name" type="string" column="name" />
<property name="salary" type="int" column="salary" />
<property name="address" type="string" column="address" />
</class>
</hibernate-mapping>
and hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">1506</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/java</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping class="Lab3.employee"/>
<mapping resource="employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
If you can use hibernate, why don't you can use JPA?
var entity = repo.getById( id );
entity.setValue( value );
repo.save(); // or repo.saveAndFlush();
I figured the following works. The code below is the update method in my execution file which is called.
public void update(int empid,String name) {
Session session = sc.openSession();
Transaction t = session.beginTransaction();
Query q = session.createQuery("from employee");
List<?> l = q.getResultList();
Iterator<?> it = l.iterator();
employee e1 = (employee) it.next();
String Address;
int Salary;
Salary=e1.getSalary();
Address=e1.getAddress().toString();
session.evict(e1);
employee e2=new employee();
e2.setEmpid(empid);
e2.setName(name);
e2.setAddress(Address);
e2.setSalary(Salary);;
session.saveOrUpdate(e2);
t.commit();
}
Try use the native sql to update
Session session = sessionFactory.openSession();
Transaction t = session.beginTransaction();
Query query = session.createQuery("update employee e set e.name = 'newvalue' where e = 1");
query.executeUpdate();
t.commit();
I agree with Jan Tibar said that Jpa is more convenient than hibernate
Supposing that we create 2 tables with below SQL :
create table Supplier (id int, name VARCHAR, count int);
create table Product (id int, name VARCHAR, description VARCHAR, price double, supplierId int);
Models:
public class Supplier {
private int id;
private String name;
private int count;
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 int getCount() { return count;}
public void setCount(int count) { this.count = count;}
}
AND
public class Product {
private int id;
private String name;
private String description;
private Double price;
private Supplier supplier;
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 String getDescription() { return description;}
public void setDescription(String description) { this.description = description; }
public Double getPrice() {return price;}
public void setPrice(Double price) { this.price = price;}
#OneToOne(targetEntity=ProductAssignment.class, mappedBy = "supplierId", fetch = FetchType.LAZY)
public Supplier getSupplier() { return supplier;}
public void setSupplier(Supplier supplier) { this.supplier = supplier; }
}
If I want to select all products order by count in supplier I can use the below code :
Criteria crit = session.createCriteria(Product.class);
Criteria critSupplier = crit.createCriteria("supplier");
critSupplier.addOrder(Order.desc("count"));
But now, I want to select all suppliers order by price in Product table.
if I want to use MySQL, the below is the script:
select * from supplier s inner join product p ON s.id = p.supplierId order by p.price
Now I want to transfer this SQL into Hibernate Criteria query in java code?
Please help me in this case?
Here you have a bidirectional relationship between two models: Supplier and Product. It is a bidirectional relationship since you want both the models to be aware of each other, and recollect each other information, based on the link that joins them (supplierId). The relationship is also a one(Supplier)-toMany(Products)
So, first off, you are missing the fact that also Supplier must be aware of the existence of the relationship. You have to express this "awareness" by modifying the Supplier model and add to it the list products:
public class Supplier implements Serializable{
private int id;
private String name;
private int count;
private List<Product> products;
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 int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
#Override
public String toString() {
return "Supplier{" + "name=" + name + '}';
}
The second step is to communicate the ORM(in your case hibernate) the relationship between your two models. Online you can find plenty of documentation that explains this subtle "step" of hibernate. in your case, something like this should do.
Hibernate mapping of Supplier:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xxx.stackoverflowdb.model.Supplier" table="Supplier">
<id column="id" name="id" type="int">
<generator class="assigned"/>
</id>
<property column="name" name="name" type="string"/>
<property column="count" name="count" type="int"/>
<bag name="products" table="product" inverse="true" lazy="false" fetch="select">
<key>
<column name="id"/>
</key>
<one-to-many class="com.xxx.stackoverflowdb.model.Product"/>
</bag>
</class>
</hibernate-mapping>
Hibernate mapping of Product:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xxx.stackoverflowdb.model.Product" table="PRODUCT">
<id column="id" name="id" type="int">
<generator class="assigned"/>
</id>
<property column="name" name="name" type="string"/>
<property column="description" name="description" type="string"/>
<property column="price" name="price" type="double"/>
<many-to-one name="supplierId" class="com.xxx.stackoverflowdb.model.Supplier" column="supplierId" insert="false" update="false" lazy="false"/>
</class>
</hibernate-mapping>
As you can see, both mapping files declare the relationship. With this set, you can write the Criteria and have it do the job. Since it now hibernate knows about the relationship, it can help you. I've created a simple tester class that demonstrates it:
public class Tester {
public static void main(String[] args) {
//gets a session, assuming your cg file is in a folder called hibernate_dispatcher
//under classpath
SessionFactory sessionFactory = new Configuration().configure("/hibernate_dispatcher/hibernate.cfg.xml")
.buildSessionFactory();
Session session = sessionFactory.openSession();
//gets a session, assuming your cg file is in a folder called hibernate_dispatcher
//under classpath
//YOUR own query --> gets all products order by count in supplier
Criteria criteria1 = session.createCriteria(Product.class);
criteria1.createAlias("supplierId", "supp");
criteria1.addOrder(Order.desc("supp.count"));
for(Object p:criteria1.list()){
Product nthP=(Product)p;
System.out.println(nthP);
}
//YOUR own query --> gets all products order by count in supplier
//the query you've asked --> gets all products order by price in Product
Criteria criteria2 = session.createCriteria(Supplier.class);
criteria2.createAlias("products", "prod");
criteria2.addOrder(Order.desc("prod.price"));
for(Object s:criteria2.list()){
Supplier nthS=(Supplier)s;
System.out.println(nthS);
}
//the query you've asked --> gets all products order by price in Product
}
}
I am learning second level caching in hibernate,
this is my entity
package com.hibernate.pojo;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
#Entity
#Table(name = "customer")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#NamedQuery(query = "select c.customerName from Customer c",name = "findCustomerNames")
public class Customer implements Serializable{
public Customer(){}
public Customer(Integer customerId){
this.customerId = customerId;
}
public Customer(Integer customerId,String customerName){
this.customerId = customerId;
this.customerName = customerName;
}
#Id
private Integer customerId;
private String customerName;
/**
* #return the customerId
*/
public Integer getCustomerId() {
return customerId;
}
/**
* #param customerId the customerId to set
*/
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
/**
* #return the customerName
*/
public String getCustomerName() {
return customerName;
}
/**
* #param customerName the customerName to set
*/
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
#Override
public String toString(){
StringBuffer strb = new StringBuffer();
strb.append("\n\n CUSTOMER-ID : ")
.append(this.customerId)
.append("\n CUSTOMER-NAME : ")
.append(this.customerName);
return strb.toString();
}
#Override
public int hashCode(){
return this.customerId * 29;
}
#Override
public boolean equals(Object object){
boolean flag = false;
if(object instanceof Customer){
Customer c = (Customer) object;
flag = (this.customerId == c.getCustomerId()) ? true : false;
}
return flag;
}
}
This is my hibernate config file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/sun-appserv-samples</property>
<property name="hibernate.connection.username">app</property>
<property name="hibernate.connection.password">app</property>
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<mapping class="com.hibernate.pojo.Customer" />
</session-factory>
</hibernate-configuration>
The code below is where my question lies
private static void getCustomer() throws Exception{
Session session = HibernateUtil.getSessionFactory().openSession();
Customer obj = null;
obj = (Customer)session.get(Customer.class, new Integer(2));
session.close();
session = HibernateUtil.getSessionFactory().openSession();
obj = (Customer)session.get(Customer.class, new Integer(2));
session.close();
session = HibernateUtil.getSessionFactory().openSession();
obj = (Customer)session.get(Customer.class, new Integer(2));
session.close();
System.out.println(obj);
}
From the code above you can see, i am opening the session thrice and close it thrice.
the query printed in the log is as follows
Hibernate:
select
customer0_.customerId as customerId0_0_,
customer0_.customerName as customer2_0_0_
from
customer customer0_
where
customer0_.customerId=?
in the logs the query is printed only once,
but when i use the below code
private static void getCustomerFromSession() throws Exception{
Session [] session = new Session[]{
HibernateUtil.getSessionFactory().openSession(),
HibernateUtil.getSessionFactory().openSession(),
HibernateUtil.getSessionFactory().openSession()
};
Customer obj1 = (Customer) session[0].get(Customer.class, new Integer(2));
Customer obj2 = (Customer) session[1].get(Customer.class, new Integer(2));
Customer obj3 = (Customer) session[2].get(Customer.class, new Integer(2));
session[0].close();
session[1].close();
session[2].close();
}
i expect here too that the query should be printed once, but the logs print
Hibernate:
select
customer0_.customerId as customerId0_0_,
customer0_.customerName as customer2_0_0_
from
customer customer0_
where
customer0_.customerId=?
Hibernate:
select
customer0_.customerId as customerId0_0_,
customer0_.customerName as customer2_0_0_
from
customer customer0_
where
customer0_.customerId=?
Hibernate:
select
customer0_.customerId as customerId0_0_,
customer0_.customerName as customer2_0_0_
from
customer customer0_
where
customer0_.customerId=?
but the query is printed thrice.
So is my second level cache configuration correct ?
Is second level cache a session specific ?
What changes i should do to my code so that even if i create 3 session, the first Customer obtained from 'get' from first session should be shared by the next two session.
so no printing for 2 select query for the same customer as its present in second level cache.
Actual queries are executed when you commit the transaction or when session is closed. As you did not close the sessions individually, each get method is executed as it is treated 3 different objects to be loaded. If close the session after each get method, then 2nd level cache is looked up and it will be retrieved for next get method. So try closing the session after each get method.
my code like like this:
I want to select data in two tables
// ArrayList<DetailType> list = null;
SessionFactory sf = null;
Session ses = null;
try {
Configuration cfg = new Configuration().configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(
cfg.getProperties()).buildServiceRegistry();
sf = cfg.buildSessionFactory(sr);
ses = sf.openSession();
// 执行查询语句
String hql = "select new DetailVoMain(d.d_id,d.d_name,m.m_name)"
+ "from MainType m, DetailType d "
+ "where d.d_main_id = m.m_id";
Query query = ses.createQuery(hql);
List<?> list = query.list();
for (int i = 0; i < list.size(); i++) {
DetailVoMain detailType = (DetailVoMain) list.get(i);
System.out.println("dId-------->" + detailType.getdId());
System.out.println("dNam-------->" + detailType.getdName());
System.out.println("mNam-------->" + detailType.getmName());
}
} catch (HibernateException e) {
System.out.println("hibernate exception");
e.printStackTrace();
} finally {
ses.close();
sf.close();
}
and myeclipese give me the error message:
hibernate exception
org.hibernate.QueryException: could not resolve property: d_id of: com.xunfang.em_mallServer.bean.DetailType [select new DetailVoMain(d.d_id,d.d_name,m.m_name)from com.xunfang.em_mallServer.bean.MainType m, com.xunfang.em_mallServer.bean.DetailType d where d.d_main_id = m.m_id]
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1968)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:313)
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:490)
at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:616)
at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:267)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:214)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:119)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:115)
at org.hibernate.hql.internal.ast.tree.DotNode.resolveSelectExpression(DotNode.java:678)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolveSelectExpression(HqlSqlWalker.java:893)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2208)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.constructor(HqlSqlBaseWalker.java:2502)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2275)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2145)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1451)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:571)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:184)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:137)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:105)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:80)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1778)
at com.xunfang.em_mallServer.util.Test.main(Test.java:39)
please help me,i test all the night!
my MainType entity like this:
public class MainType {
private String mId; // 编号
private String mName; // 类别名称
public String getmId() {
return mId;
}
public void setmId(String mId) {
this.mId = mId;
}
public String getmName() {
return mName;
}
and mapping like this:
<hibernate-mapping package="com.xunfang.em_mallServer.bean">
<class name="MainType" table="t_main_type"> <!-- 设置表名和字段对应数据 -->
<id name="mId" column="m_id" type="string">
</id>
<property name="mName" column="m_name" type="string"></property>
</class>
DetailType entity like this:
public class DetailType {
/**
* 小类编号
*/
private String dId;
/**
* 小类名称
*/
private String dName;
/**
* 归属大类编号
*/
private String dMainId;
public String getdId() {
return dId;
}
public void setdId(String dId) {
this.dId = dId;
}
public String getdName() {
return dName;
}
public void setdName(String dName) {
this.dName = dName;
}
public String getdMainId() {
return dMainId;
}
public void setdMainId(String dMainId) {
this.dMainId = dMainId;
}
and the mapping:
<hibernate-mapping package="com.xunfang.em_mallServer.bean">
<class name="DetailType" table="t_detail_type"> <!-- 设置表名和字段对应数据 -->
<id name="dId" column="d_id" type="string">
</id>
<property name="dName" column="d_name" type="string"></property>
<property name="dMainId" column="d_main_id" type="string"></property>
</class>
thank you for help me!
You should write HQL correct, use mapping property, for example dId (instead of d_id).
You need to add relationship between your entities (i.e. OneToMany, ManyToOne).
After that you can join another entity in your hql.
I'm trying to execute a stored procedure with hibernate (Java Persistence API) and postgreSQL. My mapping file looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<sql-query name="getnotificaciones" callable="true">
<return alias="notificacion"
class="tempranillo.entidades.sistemanotificaciones.NotificacionDB" lock-mode="read">
<return-property name="fecha" column="fecha"/>
<return-property name="notificacion" column="notificacioncolumn"/>
<return-property name="xmlnotificacion" column="xmlcolumn"/>
</return>
{call getnotificaciones(:idusuario)}
</sql-query>
</hibernate-mapping>
The stored procedure is shown below:
CREATE OR REPLACE FUNCTION getNotificaciones(idusuario int4,
OUT fecha date,
OUT notificacioncolumn varchar,
OUT xmlcolumn xml
)
RETURNS SETOF record
AS $$
SELECT
INFONOT.fecha,
INFONOT.notificacion,
xmlelement (name notificacion, xmlattributes(current_date as "fecha",
INFONOT.xmlTipoNotificacion as "tipoNotificacion"),
xmlelement (name infovino,
xmlforest(
tvinos.idvino,
tvinos.nombre,
tvinos.tipovino,
tvinos.anio,
tvinos.variedad,
tvinos.zona,
tvinos.pais)
),
xmlelement (name infousuario,
xmlforest(
tusuarios.idusuario,
tusuarios.ALIAS)
),
xmlelement (name infologro,
xmlforest(
tlogros.idlogro,
tlogros.nombrelogro,
tlogros.descripcion
)
)
)
FROM
public.tusuarios
INNER JOIN
(SELECT DISTINCT(xpath('//Notificacion/usuarioOrigina
/id/text()',xmlnotificacion::xml))[1]::varchar::int4 as xmlidusuario,
(xpath('//Notificacion/vino/idvino/text()',xmlnotificacion::xml
[1]::varchar::int4 as XMLIDVINO,
(xpath('//Notificacion/tipoNotificacion/text()',xmlnotificacion::xml
[1]::varchar as xmlTipoNotificacion,
(xpath('//Notificacion/Logro/IdLogro/text()',xmlnotificacion::xml
[1]::varchar::int4 as xmlIdLogro,
public.tnotificacion.idnotificacion,
public.tnotificacion.fecha,
public.tnotificacion.notificacion
FROM
public.tamistad RIGHT OUTER JOIN public.tnotificacion ON
(public.tamistad.idamigo= public.tnotificacion.idusuario)
WHERE (public.tamistad.idusuario = $1 OR public.tnotificacion.idusuario = $1) AND
public.tnotificacion.xmlnotificacion IS NOT NULL) AS INFONOT
ON (public.tusuarios.idusuario = INFONOT.xmlidusuario)
LEFT OUTER JOIN public.tvinos
on (public.tvinos.idvino = INFONOT.xmlidvino)
LEFT OUTER JOIN public.tlogros
on (public.tlogros.idlogro = INFONOT.xmlIdLogro)
ORDER BY
INFONOT.fecha DESC;
$$ LANGUAGE SQL;
The entity declared in java as follows:
package tempranillo.entidades.sistemanotificaciones;
public class NotificacionDB implements Serializable {
public NotificacionDB() {
}
public NotificacionDB(int idusuario,
Date fecha,
String notificacion) {
this.idusuario = idusuario;
this.fecha = fecha;
this.notificacion = notificacion;
}
public NotificacionDB(int idusuario,
Date fecha,
String notificacion,
String xmlnotificacion) {
this.idusuario = idusuario;
this.fecha = fecha;
this.notificacion = notificacion;
this.xmlnotificacion = xmlnotificacion;
}
private int idnotificacion;
public int getIdnotificacion() {
return idnotificacion;
}
private void setIdnotificacion(int idnotificacion) {
this.idnotificacion = idnotificacion;
}
private int idusuario;
public int getIdusuario() {
return idusuario;
}
public void setIdusuario(int idusuario) {
this.idusuario = idusuario;
}
private Date fecha;
public Date getFecha() {
return fecha;
}
public void setFecha(Date fecha) {
this.fecha = fecha;
}
private String notificacion;
public String getNotificacion() {
return notificacion;
}
public void setNotificacion(String notificacion) {
this.notificacion = notificacion;
}
private String xmlnotificacion;
public String getXmlnotificacion() {
return xmlnotificacion;
}
public void setXmlnotificacion(String xmlnotificacion) {
this.xmlnotificacion = xmlnotificacion;
}
}
When I try to execute the following code:
Query query = sesion.getNamedQuery("getnotificaciones");
query.setInteger("idusuario", idusuario);
List listanotificaciones = query.list();
I always get the same error: There is a problema with the postgreSQLDialect.
I tried with select * from getnotificaciones (:idusuario) but in this case I get "could not execute query" error message.
Can anyone help me?
It seems like Java can not take your RETURNS SETOF recordand you could find some references for that part.