hql join could not resolve property; use two tables mapping - java

I have 2 tables prod (goods) with
> id, catid(category), name, price
And cat
> with id, catname.
I wanna select like this in SQL
> select * from cat join prod on cat.id=prod.catid where
> cat.name='catname';
My query is;
Query query = session.createQuery("from prod pr join pr.cat ct with pr.catid=ct.id where ct.name=?");
I have
could not resolve property: cat of: goods.prod [from goods.prod pr
join pr.cat ct with pr.catid=ct.id where ct.name=?]
error
and in indexservice.java i have import goods.cat unused. But why? If i wrote function to use goods.prod that imports goods.cat.
Ok. that was with no mapping. I add this in cat.java
**cat.java**
package goods;
import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import goods.prod;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="cat")
public class cat implements Serializable {
private Integer id;
#Id #GeneratedValue
#Column(name="id")
#OneToMany
#JoinColumn(name="catid", referencedColumnName="id")
private List<prod> prods;
private static final long serialVersionUID = -4147058093508047162L;
private String Name;
public cat() {
}
public cat(int id, String Name) {
this.id = id;
this.Name = Name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
}
prod.java
package goods;
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.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import goods.cat;
import java.io.Serializable;
#Entity
#Table(name = "prod")
public class prod implements Serializable {
#Id #GeneratedValue
#Column(name = "catid")
private Long id;
private Integer catid;
private String name;
private Integer price;
public prod() {
}
public prod(Long id, Integer catid, String name, Integer price) {
this.id = id;
this.catid = catid;
this.name = name ;
this.price = price;
}
public Long getid() {
return id;
}
public void setid(Long id) {
this.id = id;
}
public Integer getcatid() {
return catid;
}
public void setcatid(Integer catid) {
this.catid = catid;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public Integer getprice() {
return price;
}
public void setprice(Integer price) {
this.price = price;
}
}
IndexService.java
import goods.prod;
import goods.cat;
#SuppressWarnings("unchecked")
public static ArrayList<prod> getListOfProds(String catname,String name,Integer pricel, Integer priceh){
ArrayList<prod> list = new ArrayList<prod>();
Session session = HibernateUtil.openSession();
Transaction tx = null;
try {
tx = session.getTransaction();
tx.begin();
Query query = session.createQuery("from prod pr join pr.cat ct with pr.catid=ct.id where ct.name=?");
//Query query = session.createQuery("from prod pr join pr.cat ct with pr.catid=ct.id where ct.name=?");
query.setString(0, catname);
//query.setInteger(1, pricel);
//query.setInteger(2, priceh);
list = (ArrayList<prod>) query.list();
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
return list;
}

In your prod class (defined in prod.java) you have not mapped a field cat (as object type cat), you have mapped only catId as integer.
So you can't use a join like yours.
You can re-write your query like this:
FROM prod pr, cat ct
WHERE pr.catid = ct.id
AND ct.name = ?

manytoone
another variant
public class prod implements Serializable {
#Id #GeneratedValue
#Column(name = "catid")
#ManyToOne
#JoinColumn(name="cat", referencedColumnName="id")
// private Integer catid;
private Long id;
private cat cat;
private String name;
private Integer price;
#Column(s) not allowed on a #ManyToOne property: goods.prod.id

Related

Use of #OneToMany or #ManyToMany targeting an unmapped class (Category,SubCategory,Product)

I devised Category,SubCategory and Product entities for JSF project and I had an issue about mapping between SubCategory and Product with ManytoMany relation. Here are Category,SubCategory and Products below. How can I solve out this mapping excepiton. Thks.
#Entity
#Table(name="CATEGORY",schema="DEMO")
public class Category implements Serializable{
#Id
#SequenceGenerator(name="catseq",sequenceName="seqCatSEQ",allocationSize=1)
#GeneratedValue(generator="catseq",strategy=GenerationType.SEQUENCE)
#Column(name="ID")
private Integer id;
#Column(name="NAME")
private String name;
#Column(name="CAT_DESC")
private String catDesc;
#OneToMany(cascade = { CascadeType.PERSIST },mappedBy="category")
private Set<SubCategory> subcategories = new HashSet();
public Category() {
super();
// TODO Auto-generated constructor stub
}
public Category(String name, String catDesc) {
super();
this.name = name;
this.catDesc = catDesc;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCatDesc() {
return catDesc;
}
public void setCatDesc(String catDesc) {
this.catDesc = catDesc;
}
public Set<SubCategory> getSubcategories() {
return subcategories;
}
public void setSubcategories(Set<SubCategory> subcategories) {
this.subcategories = subcategories;
}
}
SubCategory:
package entities;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="SUBCATEGORY",schema="DEMO")
public class SubCategory implements Serializable{
#Id
#SequenceGenerator(name="subcatseq",sequenceName="seqSubCatSEQ",allocationSize=1)
#GeneratedValue(generator="subcatseq",strategy=GenerationType.SEQUENCE)
#Column(name="ID")
private Integer id;
#Column(name="SUBNAME")
private String SubName;
#Column(name="SUBNAME_DESC")
private String SubNameDes;
#ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
#JoinColumn(name = "CAT_ID")
private Category category;
#ManyToMany(cascade=CascadeType.PERSIST,mappedBy="subcategories")
Set<Product> products = new HashSet<Product>();
public SubCategory() {
super();
// TODO Auto-generated constructor stub
}
public SubCategory(String subName, String subNameDes) {
super();
SubName = subName;
SubNameDes = subNameDes;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSubName() {
return SubName;
}
public void setSubName(String subName) {
SubName = subName;
}
public String getSubNameDes() {
return SubNameDes;
}
public void setSubNameDes(String subNameDes) {
SubNameDes = subNameDes;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
Product:
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="PRODUCTS",schema="DEMO")
public class Product implements Serializable{
#Id
#SequenceGenerator(name="proseq",sequenceName="proSEQ",allocationSize=1)
#GeneratedValue(generator="proseq",strategy=GenerationType.SEQUENCE)
#Column(name="ID")
private Integer id;
#Column(name="NAME")
private String productName;
#Column(name="QUANTITY")
private Integer quantity;
#Column(name="PRICE")
private Double price;
#Column(name="PRODUCT_DESC")
private String productDes;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name="PRODUCT_SUBCATEGORY",
joinColumns={#JoinColumn(name="PRODUCT_ID")},
inverseJoinColumns={#JoinColumn(name="SUBCATEGORY_ID")}
)
Set<SubCategory> subcategories = new HashSet<SubCategory>();
public Product() {
super();
// TODO Auto-generated constructor stub
}
public Product(String productName, Integer quantity, Double price, String productDes,
Set<SubCategory> subcategories) {
super();
this.productName = productName;
this.quantity = quantity;
this.price = price;
this.productDes = productDes;
this.subcategories = subcategories;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getProductDes() {
return productDes;
}
public void setProductDes(String productDes) {
this.productDes = productDes;
}
public Set<SubCategory> getSubcategories() {
return subcategories;
}
public void setSubcategories(Set<SubCategory> subcategories) {
this.subcategories = subcategories;
}
}
First mappedby is defined as It refers to the field who owns the relationship, By other meaning mapped by refers to the table class which has the foreign key
So we have two mappedBy that are suspiecous lets take them one by one :
1-
#OneToMany(cascade = { CascadeType.PERSIST },mappedBy="category")
private Set<SubCategory> subcategories = new HashSet();
That means that subcategory table and class owns the relationship field so subcategory table is the one who have the foreign key and from SubCategory class the foreign key name is CAT_ID so this one is OK.
2-
#ManyToMany(cascade=CascadeType.PERSIST,mappedBy="subcategories")
Set<Product> products = new HashSet<Product>();
Ok this one shows that there is a field called subcategories in Product class this one owns the relationship BAM this is not true since this is ManyToMany the owner of the relationship should be a third table exists on database and have to be logically understood by hibernate
So this is the issue mappedBy refers to the the field which is not the owner of the relationship and since the owner is some anonymous entity
this have to be like this :
#ManyToMany(cascade=CascadeType.PERSIST)
#JoinTable(name="PRODUCT_SUBCATEGORY",
joinColumns={#JoinColumn(name="SUBCATEGORY_ID")},
inverseJoinColumns={#JoinColumn(name="PRODUCT_ID")}
Set<Product> products = new HashSet<Product>();
Note Your PRODUCT_SUBCATEGORY table should only have two primary keys and should be primary so that hibernate understands that this is ManyToMany relationship

org.hibernate.hql.internal.ast.QuerySyntaxException Invalid path

I devised category and subcategory form in jsf. When I select any category, subcategory related with this category are shown in dropdown. I have a issue how to write hql file. Category and Subcategory is depended on onetomany and vice versa.
Here is the subcategory dao below.
public List getAllSubCategoriesSelectItemName(String name) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getSessionFactory().openSession();
try {
List<Category> liste = session.createQuery("Select S.SubName from SubCategory S left join SC.category scc where scc.name='"+name+"'").list();
return liste;
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
return null;
}
#Entity
#Table(name="CATEGORY",schema="DEMO")
public class Category implements Serializable{
#Id
#SequenceGenerator(name="catseq",sequenceName="seqCatSEQ",allocationSize=1)
#GeneratedValue(generator="catseq",strategy=GenerationType.SEQUENCE)
#Column(name="ID")
private Integer id;
#Column(name="NAME")
private String name;
#Column(name="CAT_DESC")
private String catDesc;
#OneToMany(cascade = { CascadeType.PERSIST },mappedBy="category")
private Set<SubCategory> subcategories = new HashSet();
public Category() {
super();
// TODO Auto-generated constructor stub
}
public Category(String name, String catDesc) {
super();
this.name = name;
this.catDesc = catDesc;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCatDesc() {
return catDesc;
}
public void setCatDesc(String catDesc) {
this.catDesc = catDesc;
}
public Set<SubCategory> getSubcategories() {
return subcategories;
}
public void setSubcategories(Set<SubCategory> subcategories) {
this.subcategories = subcategories;
}
}
package entities;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="SUBCATEGORY",schema="DEMO")
public class SubCategory implements Serializable{
#Id
#SequenceGenerator(name="subcatseq",sequenceName="seqSubCatSEQ",allocationSize=1)
#GeneratedValue(generator="subcatseq",strategy=GenerationType.SEQUENCE)
#Column(name="ID")
private Integer id;
#Column(name="SUBNAME")
private String SubName;
#Column(name="SUBNAME_DESC")
private String SubNameDes;
#ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
#JoinColumn(name = "CAT_ID")
private Category category;
#ManyToMany(cascade=CascadeType.PERSIST,mappedBy="subcategories")
Set<Product> products = new HashSet<Product>();
public SubCategory() {
super();
// TODO Auto-generated constructor stub
}
public SubCategory(String subName, String subNameDes) {
super();
SubName = subName;
SubNameDes = subNameDes;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSubName() {
return SubName;
}
public void setSubName(String subName) {
SubName = subName;
}
public String getSubNameDes() {
return SubNameDes;
}
public void setSubNameDes(String subNameDes) {
SubNameDes = subNameDes;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
Select S.SubName from SubCategory S left join SC.category
There is nothing aliased with SC in that query.The only existing alias is S. So SC.category is incorrect.

Hibernate oneToOne mapping not reading joinColumn class instance

package com.hibernatetest;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
#Entity
#Table(name = "country")
public class Country {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "ctry_id")
private Integer id;
#Column(name = "ctry_name")
private String name;
#Transient
private int rank;
#ManyToOne
#JoinColumn(name="fk_cont_id")
private Continent continent;
#OneToOne(mappedBy="country")
private HeadOfState hos;
public HeadOfState getHos() {
return hos;
}
public void setHos(HeadOfState hos) {
this.hos = hos;
}
public Continent getContinent() {
return continent;
}
public Country() {
;
}
public Country(String name) {
this.name = name;
}
public void setContinent(Continent continent) {
this.continent = continent;
}
public Integer getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setRank(int rank) {
this.rank = rank;
}
public int getRank() {
return rank;
}
public void addCountryToDb(Continent cont) {
continent = cont;
}
}
package com.hibernatetest;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="hos")
public class HeadOfState {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="hos_id")
private Integer id;
#Column(name="hos_name")
private String name;
#OneToOne
#JoinColumn(name="fk_ctry_id")
private Country country;
public HeadOfState() {
}
public HeadOfState(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
Session session = HibernateUtil.getSessionFactory().openSession();
try {
Transaction transaction = session.getTransaction();
Country countObj = (Country)session.get(Country.class, 62);
HeadOfState hos = new HeadOfState("ghanaKing");
hos.setCountry(countObj);
transaction.begin();
session.save(hos);
transaction.commit();
Country cont = (Country)session.get(Country.class, 62);
System.out.println("name of country is "+cont.getName());
System.out.println("name of continent is "+cont.getContinent().getName());
HeadOfState newhos = cont.getHos();
if (newhos == null) {
throw new Exception("hos obj is null even after storing it");
}
System.out.println("Name of HOS is "+cont.getHos().getName());
} catch (Exception ex) {
System.out.println("exception has happened: "+ex.getMessage());
throw ex;
} finally {
session.close();
HibernateUtil.shutdown();
}
}
Output of the SQL table even with the exception in the code
ysql> select * from hos;
host_id, hos_name, fk_ctry_id
2, ghanaKing,62
1 row in set (0.00 sec)
mysql> select * from country
ctry_id, ctry_name, fk_cont_id
60, England, 30
62, ghana, 30
Eclipse exception
name of country is ghana
name of continent is Asia
exception has happened hos obj is null even after storing it
Nov 24, 2014 2:54:29 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://172.23.180.81:3306/test]
Exception in thread "main" java.lang.Exception: hos obj is null even after storing it
at com.hibernatetest.SqlTest.main(SqlTest.java:37)
try to set related objects on both sides of association.
When you save your instances :
hos.setCountry(countObj);
and add
countObj.setHos(hos);
You could add a convinient method to either of your instances like, therefore you would call one method insead of two.

In Hibernate 4, inner join is used for child objects while accessing objects of "one table per subclass"

In Hibernate 4, inner join is used for child objects while accessing objects of "one table per subclass".
[Edit: This is a bug in Hibernate 4.3.5, and it is going to be fixed in 4.3.6. https://hibernate.atlassian.net/browse/HHH-8980 ]
I have the following classes.
Professor - Base Class
ContractProfessor - Derived Class from Professor
FulltimeProfessor - Derived Class from Professor
FulltimeProfessor contains a mandatory object of Department. [Not null at SQL]
Classroom contains an object of Professor, which can be null.
When I query Classroom, I am getting errors. When I saw the query, it is doing inner join with Department. If the classroom that it is retrieving is of ContractProfessor, then it won't have Department, and the inner join fails, and it is throwing exception.
Since, the Professor object can be null, it should always use left join for all the joins. But, it is doing inner join between FulltimeProfessor and Department. Because of that, I am getting exceptions when I try to retrieve Classroom objects.
This is working fine in Hibernate 3. But, when I use hibernate 4.3.5-Final, I am getting errors.
What should I do to fix this without changing the DB schema?
The following is the code and sql for the same.
Generated Query in Hibernate 4.3.5-Final
select
professor0_.id as id1_6_0_,
professor0_.name as name2_6_0_,
professor0_1_.hourlyRate as hourlyRa1_2_0_,
professor0_2_.DepartmentId as Departme3_4_0_,
professor0_2_.salary as salary1_4_0_,
case
when professor0_1_.id is not null then 1
when professor0_2_.id is not null then 2
when professor0_.id is not null then 0
end as clazz_0_,
department1_.id as id1_3_1_,
department1_.name as name2_3_1_
from
Professor professor0_
left outer join
ContractProfessor professor0_1_
on professor0_.id=professor0_1_.id
left outer join
FulltimeProfessor professor0_2_
on professor0_.id=professor0_2_.id
inner join
Department department1_
on professor0_2_.DepartmentId=department1_.id
where
professor0_.id=?
Generated Query in Hibernate 3.
select
professor0_.id as id2_1_,
professor0_.name as name2_1_,
professor0_1_.hourlyRate as hourlyRate3_1_,
professor0_2_.DepartmentId as Departme3_8_1_,
professor0_2_.salary as salary8_1_,
case
when professor0_1_.id is not null then 1
when professor0_2_.id is not null then 2
when professor0_.id is not null then 0
end as clazz_1_,
department1_.id as id1_0_,
department1_.name as name1_0_
from
Professor professor0_
left outer join
ContractProfessor professor0_1_
on professor0_.id=professor0_1_.id
left outer join
FulltimeProfessor professor0_2_
on professor0_.id=professor0_2_.id
left outer join
Department department1_
on professor0_2_.DepartmentId=department1_.id
where
professor0_.id=?
Professor.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
#Entity
#Table(name = "Professor")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Professor {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
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 toString() {
return "Professor id: " + getId() + " name: " + getName();
}
}
ContractProfessor.java
import javax.persistence.Entity;
import javax.persistence.Table;
#Entity
#Table(name="ContractProfessor")
public class ContractProfessor extends Professor {
private long hourlyRate = 1;
public long getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(long hourlyRate) {
this.hourlyRate = hourlyRate;
}
public String toString() {
return "ContractProfessor id: " + getId() + " name: " + getName();
}
}
FulltimeProfessor.java
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
#Entity
#Table(name="FulltimeProfessor")
public class FulltimeProfessor extends Professor {
private long salary = 1;
#ManyToOne(fetch = FetchType.EAGER)
#Fetch(FetchMode.JOIN)
#JoinColumn(name = "DepartmentId", nullable = false)
private Department department;
public Department getDepartment()
{
return department;
}
public void setDepartment(Department department)
{
this.department = department;
}
public long getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public String toString() {
return "FullTimeProfessor id: " + getId() + " name: " + getName();
}
}
Department.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "Department")
public class Department
{
private long id;
private String name;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Department id: " + getId() + " name: " + getName();
}
}
Classroom.java
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;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
#Entity
#Table(name = "Classroom")
public class Classroom
{
private long id;
private String name;
private Professor professor;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Classroom id: " + getId() + " name: " + getName();
}
#ManyToOne(fetch = FetchType.EAGER)
#Fetch(FetchMode.JOIN)
#JoinColumn(name = "ProfessorId", nullable = true)
public Professor getProfessor()
{
return professor;
}
public void setProfessor(Professor professor)
{
this.professor = professor;
}
}
InnerJoinMain.java
import java.util.Collection;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
public class InnerJoinMain
{
public static void main(String[] args) throws Exception
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ProfessorService");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
int time = (int)((new Date().getTime() / 1000) % 10000);
System.out.println(time);
ContractProfessor cprof = new ContractProfessor();
cprof.setName("CProf" + time);
cprof.setHourlyRate(time);
em.persist(cprof);
Department dept = new Department();
dept.setName("Dept" + time);
em.persist(dept);
FulltimeProfessor fprof = new FulltimeProfessor();
fprof.setName("Fprof" + time);
fprof.setDepartment(dept);
fprof.setSalary(time + 10);
em.persist(fprof);
Classroom cls = new Classroom();
cls.setName("Classroom" + time);
cls.setProfessor(cprof);
em.persist(cls);
cls = new Classroom();
cls.setName("Classroom" + (time+1));
cls.setProfessor(fprof);
em.persist(cls);
cls = new Classroom();
cls.setName("Classroom" + (time+2));
em.persist(cls);
em.getTransaction().commit();
em.getTransaction().begin();
Query query = em.createQuery("SELECT c FROM Classroom c");
for(Classroom c : (Collection<Classroom>) query.getResultList()) {
System.out.println(c);
}
em.getTransaction().commit();
em.close();
emf.close();
}
}

one to one bidirectional hibernate mapping

I was trying to implement hibernate one-to-one bidirectional mapping between Person class and Address class using annotation. While running the program it gave me some errors
org.hibernate.TransientObjectException: object references an unsaved transient
instance - save the transient instance before flushing: com.vaannila.domain.Person
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:242)
at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:597)
at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3123)
at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:479)
at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:204)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:127)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.vaannila.domain.Add.main(Add.java:58)
following are my classes
Person.java
package com.vaannila.domain;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "PERSON")
public class Person implements Serializable {
private long personId;
private String personName;
private Address personAddress;
private Set<Phone> personPhoneNumbers = new HashSet<Phone>(0);
public Person() {
}
public Person(String personName, Address personAddress, Set<Phone> personPhoneNumbers) {
this.personName = personName;
this.personAddress = personAddress;
this.personPhoneNumbers = personPhoneNumbers;
}
#Id
#GeneratedValue
#Column(name = "PERSON_ID")
public long getPersonId() {
return this.personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
#Column(name = "PERSON_NAME", nullable = false, length = 100)
public String getPersonName() {
return this.personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
#OneToOne(cascade = CascadeType.ALL)
public Address getPersonAddress() {
return this.personAddress;
}
public void setPersonAddress(Address personAddress) {
this.personAddress = personAddress;
}
#OneToMany
#JoinTable(name = "PERSON_PHONE", joinColumns =
{ #JoinColumn(name = "PERSON_ID") }, inverseJoinColumns =
{ #JoinColumn(name = "PHONE_ID") })
public Set<Phone> getPersonPhoneNumbers() {
return personPhoneNumbers;
}
public void setPersonPhoneNumbers(Set<Phone> personPhoneNumbers) {
this.personPhoneNumbers = personPhoneNumbers;
}
}
Addres.java
package com.vaannila.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "ADDRESS")
public class Address implements Serializable {
private long addressId;
private String street;
private String city;
private String state;
private String zipcode;
private Person person;
public Address() {
}
#Id
#GeneratedValue
#Column(name = "ADDRESS_ID")
public long getAddressId() {
return this.addressId;
}
public void setAddressId(long addressId) {
this.addressId = addressId;
}
#Column(name = "ADDRESS_STREET", nullable = false, length=250)
public String getStreet() {
return this.street;
}
public void setStreet(String street) {
this.street = street;
}
#Column(name = "ADDRESS_CITY", nullable = false, length=50)
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
#Column(name = "ADDRESS_STATE", nullable = false, length=50)
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
#Column(name = "ADDRESS_ZIPCODE", nullable = false, length=10)
public String getZipcode() {
return this.zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
#OneToOne
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Phone.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.vaannila.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*
* #author junaid
*/
#Entity
#Table(name = "PHONE")
public class Phone implements java.io.Serializable {
private long phoneId;
private String phoneType;
private String phoneNumber;
public Phone() {
}
public Phone(String phoneType, String phoneNumber) {
this.phoneType = phoneType;
this.phoneNumber = phoneNumber;
}
#Id
#GeneratedValue
#Column(name = "PHONE_ID")
public long getPhoneId() {
return this.phoneId;
}
public void setPhoneId(long phoneId) {
this.phoneId = phoneId;
}
#Column(name = "PHONE_TYPE", nullable = false, length=10)
public String getPhoneType() {
return this.phoneType;
}
public void setPhoneType(String phoneType) {
this.phoneType = phoneType;
}
#Column(name = "PHONE_NUMBER", nullable = false, length=15)
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
Main class
package com.vaannila.domain;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.vaannila.util.HibernateUtil;
import java.util.HashSet;
import java.util.Set;
public class Add {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
//Transaction for person 1 start
Address address1 = new Address();
address1.setCity("Bangalore");
address1.setState("Karnataka");
address1.setStreet("Ring Road");
address1.setZipcode("560000");
Set<Phone> phoneNumbers = new HashSet<Phone>();
phoneNumbers.add(new Phone("house","32354353"));
phoneNumbers.add(new Phone("mobile","9889343423"));
Person person = new Person();
person.setPersonName("Junaid");
person.setPersonAddress(address1);
person.setPersonPhoneNumbers(phoneNumbers);
session.save(person);
//Transaction for person 1 end
//Transaction for person 2 start
Set<Phone> phoneNumbers2 = new HashSet<Phone>();
phoneNumbers2.add(new Phone("house","32354353"));
phoneNumbers2.add(new Phone("mobile","9889343423"));
Person person1 = new Person();
person1.setPersonName("Wayne");
person1.setPersonPhoneNumbers(phoneNumbers2);
Address address2 = new Address();
address2.setCity("Chennai");
address2.setState("Tamil Nadu");
address2.setStreet("OMR Road");
address2.setZipcode("4000");
address2.setPerson(person1);
session.save(address2);
//Transaction for person 2 end
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
All tables are getting created, but when deleting the table, all except Person and Address is not getting deleted.
Can anyone please help me?
Thanks in advance.
Got it working guys.
i missed out mappedBy property. After adding that its working fine.
#OneToOne(mapperdBy="personAddress")
public Person getPerson() {
return person;
}

Categories