I am trying to perform join in hibernate and i am using struts2.
I am working with hibernate using annotaions. Now i am unable to perform join between two tables.My first table is "studentprojects" which contain pid and email.Second table is "initialprojectdetials" which contains pid,name,description... similarly some other fields.I have to get the data of second table by performing join around pid of first table.
For this am using this query:
String hql="from InitialProjectDTO I join I.projectId S where I.projectId=:id";
Query query=session.createQuery(hql);
query.setParameter("id", id);
mail =query.list();
where mail is the arraylist of InitialProjectDTO.
And my InitialProjectDTO is:
package edu.pma.dto;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="initialprojectdetail")
public class InitialProjectDTO {
#Id
#Column(name="projectId")
#OneToMany(cascade=CascadeType.ALL)
#JoinTable(name="studentprojects",joinColumns=#JoinColumn(name="projectId"))
int projectId;
#Column(name="name")
String name;
#Column(name="description")
String description;
#Column(name="technology")
String technology;
#Column(name="guide")
String guide;
#Column(name="duration")
int duration;
#Column(name="status")
String status;
#Column(name="report")
String report;
public String getReport() {
return report;
}
public void setReport(String report) {
this.report = report;
}
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
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 String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getGuide() {
return guide;
}
public void setGuide(String guide) {
this.guide = guide;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
my SudentProjectDTO is:
package edu.pma.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="studentprojects")
public class StudentProjectDTO {
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
#Id
#Column(name="email")
String email;
#Column(name="projectId")
int projectId;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
This is the error which i am getting:
Illegal attempt to map a non collection as a #OneToMany, #ManyToMany or #CollectionOfElements: edu.pma.dto.InitialProjectDTO.projectId
Method "execute" failed for object edu.pma.actions.LoginAction#1096a56
File: org/hibernate/cfg/annotations/CollectionBinder.java
You should try to use different models
#Entity
public class InitialProjectDTO {
#OneToMany(mappedBy = "project")
private Collection<StudentProjectDTO> students;
}
#Entity
public class StudentProjectDTO {
#ManyToOne
private InitialProjectDTO project;
}
And with the proper model it shuld be easy to write hql, you might want to look here for examples https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html.
Also I would suggest to look here for example of models. http://viralpatel.net/blogs/hibernate-one-to-many-annotation-tutorial/
See following example might its help to you
#Entity
#Table(name="initialprojectdetail")
public class InitialProjectDTO {
private Integer initialProjectDTOId;
private Set<StudentProjectDTO > studentProjectDTO = new HashSet<StudentProjectDTO >(0);
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "initial_projectDTO_id", unique = true, nullable = false)
public Integer getInitialProjectDTOId() {
return this.initialProjectDTOId;
}
public void setInitialProjectDTOId(Integer initialProjectDTOId) {
this.initialProjectDTOId = initialProjectDTOId;
}
#OneToMany(mappedBy = "studentprojects", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
public Set<StudentProjectDTO> getUserRole() {
return this.studentProjectDTO;
}
public void setUserRole(Set<StudentProjectDTO> studentProjectDTO) {
this.studentProjectDTO = studentProjectDTO;
}
}
#Entity
#Table(name="studentprojects")
public class StudentProjectDTO {
private InitialProjectDTO project;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "initial_projectDTO_id", nullable = false)
public User getProject() {
return this.project;
}
public void setProject(InitialProjectDTO project) {
this.project = project;
}
}
your Query shoud be something like this
String hql="SELECT ip from InitialProjectDTO ip JOIN ip.studentProjectDTO sp WHERE sp.projectId = :id";
Query query=session.createQuery(hql);
query.setParameter("id", id);
mail =query.list();
Related
I have two table on MySql database. Item, ItemGroup which are related by Item.groupid -> ItemGroup.id I am also using hibernate-entitymanager and spring boot. Here are my entity classes for Item and ItemGroup.
Item.java
package com.thiha.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String createdDate;
private String modifiedDate;
private String itemCode;
private String description;
private int groupId;
private double quantity;
private double price;
private int recordStatus;
private ItemGroup itemGroup;
#ManyToOne
#JoinColumn(name = "groupid")
public ItemGroup getItemGroup() {
return itemGroup;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
public String getItemCode() {
return itemCode;
}
public void setItemCode(String itemCode) {
this.itemCode = itemCode;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public double getQuantity() {
return quantity;
}
public void setQuantity(double quantity) {
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getRecordStatus() {
return recordStatus;
}
public void setRecordStatus(int recordStatus) {
this.recordStatus = recordStatus;
}
}
ItemGroup.java
package com.thiha.entities;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class ItemGroup {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String createdDate;
private String modifiedDate;
private String groupCode;
private String groupName;
private int recordStatus;
private List<Item> items;
#OneToMany(mappedBy = "itemGroup", cascade = CascadeType.ALL)
public List<Item> getItems(){
return items;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
public String getGroupCode() {
return groupCode;
}
public void setGroupCode(String groupCode) {
this.groupCode = groupCode;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public int getRecordStatus() {
return recordStatus;
}
public void setRecordStatus(int recordStatus) {
this.recordStatus = recordStatus;
}
}
I also create a foreign keys in Item table reference to ItemGroup table with foreign key groupid. But when I run the code with mvn spring-boot:run, I got some exception as following:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: item_group, for columns: [org.hibernate.mapping.Column(items)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:431)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:398)
at org.hibernate.mapping.Property.isValid(Property.java:225)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:595)
at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
If I remove the relationships in both class, it is working properly but I cannot make INNER JOIN query. Please help me to solve this problem
You can't mix annotation conventions in Hibernate. Please try to move your #Id and #GeneratedValue annotations to getter, or #OneToMany and #ManyToOne to fields.
It says
Could not determine type for: java.util.List, at table: item_group, for columns: [org.hibernate.mapping.Column(items)]'
Because your mappedBy is incorrect.
When you put annotation on getter getCategory(), hibernate understands that it's category.
#ManyToOne
#JoinColumn(name = "groupid")
public ItemGroup getCategory() {
return itemGroup;
}
So, please use appropriate name in your class ItemGroup
#OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
public List<Item> getItems(){
return items;
}
dont worry there is do only one thing remove your annotation of #Id and #generatorValue annotation above on the id and put on the getter method of your id
the problem will be fix.....!
I have User and Employee tables on MySQL, and there is employeeId as foreign key in User table.
Now I need to get Employees who do not have User.
I write this SQL in MySQL Workbench, this works exactly how I want:
SELECT * FROM HUMANRESOURCE.EMPLOYEE E LEFT JOIN AUTHORIZE.USER U
ON U.EMPLOYEEOBJID = E.OBJID
WHERE U.EMPLOYEEOBJID is NULL;
But when I try to implement this SQL as JPA query, it returns nothing. Here is JPA Query:
Query query = em.createQuery("SELECT e FROM Employee e LEFT JOIN User u
WHERE u.employee.objid = e.objid
AND u.employee IS NULL");
And here is truely working JPA Query that I use for getting Employees who have user:
Query query = em.createQuery("SELECT e FROM Employee e INNER JOIN User u
WHERE u.employee.objid = e.objid");
What am I doing wrong here?
Update for entity classes:
Base.java
package com.kadir.entity;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
#Cacheable
#MappedSuperclass
public abstract class Base {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "OBJID")
private BigInteger objid;
#Column(name = "CREATEDBY")
private String createdby;
#Column(name = "CREATEDDATE")
private Timestamp createddate;
#Version
#Column(name = "ROWVERSION")
private Integer rowversion;
#Column(name = "UPDATEDBY")
private String updatedby;
#Column(name = "UPDATEDDATE")
private Timestamp updateddate;
#Column(name = "ARCHIVED", columnDefinition = "int default 0")
private int archived;
public BigInteger getObjid() {
return this.objid;
}
public void setObjid(BigInteger objid) {
this.objid = objid;
}
public String getCreatedby() {
return this.createdby;
}
public void setCreatedby(String createdby) {
this.createdby = createdby;
}
public Date getCreateddate() {
return this.createddate;
}
public void setCreateddate(Timestamp createddate) {
this.createddate = createddate;
}
public Integer getRowversion() {
return this.rowversion;
}
public void setRowversion(Integer rowversion) {
this.rowversion = rowversion;
}
public String getUpdatedby() {
return this.updatedby;
}
public void setUpdatedby(String updatedby) {
this.updatedby = updatedby;
}
public Timestamp getUpdateddate() {
return this.updateddate;
}
public void setUpdateddate(Timestamp updateddate) {
this.updateddate = updateddate;
}
public int getArchived() {
return archived;
}
public void setArchived(int archived) {
this.archived = archived;
}
}
Employee.java
package com.kadir.entity.humanresource;
import com.kadir.entity.corporation.Company;
import com.kadir.entity.Base;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the EMPLOYEE database table.
*
*/
#Cacheable
#Entity
#Table(name = "EMPLOYEE", schema = "HUMANRESOURCE")
#NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
public class Employee extends Base implements Serializable {
private static final long serialVersionUID = 1L;
#ManyToOne
#JoinColumn(name = "COMPANYOBJID")
private Company company;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "GENDER")
private int gender;
#Column(name = "EMAIL")
private String email;
#Column(name = "PHONE")
private String phone;
#Column(name = "LASTNAME")
private String lastname;
public Employee() {
}
public Company getCompany() {
return this.company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public int getGender() {
return this.gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
User.java
package com.kadir.entity.authorize;
import com.kadir.entity.Employee;
import com.kadir.entity.Base;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the USER database table.
*
*/
#Cacheable
#Entity
#Table(name="USER", schema="AUTHORIZE")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User extends Base implements Serializable {
private static final long serialVersionUID = 1L;
#OneToOne
#JoinColumn(name="EMPLOYEEOBJID")
private Employee employee;
#Column(name="NAME")
private String name;
#Column(name="PASSWORD")
private String password;
public User() {
}
public Employee getEmployee() {
return this.employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
EclipseLink has support for the ON clause, so try using
"SELECT e FROM Employee e LEFT JOIN User u on u.employee = e WHERE u.employee IS NULL"
You can also use exist and a subquery:
"select e from Employee e where not exists (select 1 from User u where u.employee = e)"
In my case, I'm using Apache OpenJPA.
Query should be something like this:
SELECT e FROM Employee e LEFT JOIN e.user u WHERE u.employeeId IS NULL
I had similar error. I had conditional OneToOne relation. I fixed problem like that.
#Query("SELECT e FROM Employee e LEFT OUTER JOIN User u ON u = e.user " +
"WHERE (u IS NULL OR e.condition = :conditionValue) ")
I get the mapped entity always null but, FetchType.EAGER is set already. I have a Booking entity class that maps to two other entities - Slot and Subscriber. Both the entities are null when I fetch the booking entity
Booking class
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
#Entity
#Table(name = "BOOKING")
public class Booking {
public Booking(){
}
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "title")
private String title;
#Column(name = "descr")
private String desc;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "slotid",insertable = false, updatable = false)
private Slot slot;
private Integer slotid;
private Integer subscriberid;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "subscriberid",insertable = false, updatable = false)
private User subscriber;
#Column(name = "created")
#Temporal(TemporalType.TIMESTAMP)
private Date created;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "slotid",referencedColumnName="slotid")
public Slot getSlot() {
return slot;
}
public void setSlot(Slot slot) {
this.slot = slot;
}
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "subscriberid",referencedColumnName="userid")
public User getSubscriber() {
return subscriber;
}
public void setSubscriber(User subscriber) {
this.subscriber = subscriber;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getSlotid() {
return slotid;
}
public void setSlotid(Integer slotid) {
this.slotid = slotid;
}
public Integer getSubscriberid() {
return subscriberid;
}
public void setSubscriberid(Integer subscriberid) {
this.subscriberid = subscriberid;
}
}
Slot class
import java.util.Date;
import javax.persistence.Column;
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.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
#Entity
#Table(name="SLOT")
public class Slot {
public Slot(){
}
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="slotid")
private Integer id;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="ownerid",insertable = false, updatable = false)
private User user;
#Column(name="startdate")
private Date startdate;
#Column(name="enddate")
private Date enddate;
#Column(name="status")
private String status;
private Integer ownerid;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created", nullable = false, updatable=false)
#Version
private Date created;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public User getUser() {
return this.user;
}
public void setUser(User owner) {
this.user = owner;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getOwnerid() {
return ownerid;
}
public void setOwnerid(Integer ownerid) {
this.ownerid = ownerid;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getStartdate() {
return startdate;
}
public void setStartdate(Date startdate) {
this.startdate = startdate;
}
public Date getEnddate() {
return enddate;
}
public void setEnddate(Date enddate) {
this.enddate = enddate;
}
}
Subscriber - User class
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name="users")
public class User {
public User(){
}
#Id#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="userid")
private Integer userid = 0;
#Column(name = "name")
private String name;
#Column(name = "mobile")
private String mobile;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
#Column(name = "type")
private String userType;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="cityid",insertable = false, updatable = false)
private City city;
private String cityid;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="specialityid",insertable = false, updatable = false)
private Speciality speciality;
private Integer specialityid;
#Column(name="medregno")
private String regno;
#Column(name="refcode")
private String referalcode;
public String getRegno() {
return regno;
}
public void setRegno(String regno) {
this.regno = regno;
}
public String getReferalcode() {
return referalcode;
}
public void setReferalcode(String referalcode) {
this.referalcode = referalcode;
}
#Column(name = "gender")
private String gender;
#Column(name = "active")
private boolean active;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updated")
private Date updated;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created")
private Date created;
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (userid != other.userid)
return false;
return true;
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public String getCityid() {
return cityid;
}
public void setCityid(String cityid) {
this.cityid = cityid;
}
public Speciality getSpeciality() {
return speciality;
}
public void setSpeciality(Speciality speciality) {
this.speciality = speciality;
}
public Integer getSpecialityid() {
return specialityid;
}
public void setSpecialityid(Integer specialityid) {
this.specialityid = specialityid;
}
}
booking.getSlot() and booking.getSubscriber() returns null
Please let me know if i miss some configuration while mapping
EDIT1
Added code how the entity is getting loaded
public Booking addBooking(String title,String desc,int slotid,int subscriberid,Session session){
Booking booking = new Booking();
booking.setTitle(title);
booking.setDesc(desc);
booking.setSlotid(slotid);
booking.setSubscriberid(subscriberid);
booking.setCreated(new Date());
Integer bookingid = (Integer) session.save(booking);
session.flush();
Booking bookingEntity = (Booking) session.createQuery("From Booking where id = ?").
setParameter(0, bookingid).list().get(0);
return bookingEntity;
}
I am saving the entity and reloading it.
It's not working because Hibernate is retuning the same instance it has already in its 1st level cache, which doesn't have a reference to any of the 2 other entities.
To fix this, you have to do a session.refresh(booking) rather than executing a query.
In your code :
booking.setSlotid(slotid);
booking.setSubscriberid(subscriberid);
You're just setting Integer values and not objects. Instead of this, try to set objects :
booking.setSlot(new Slot(slotid));
booking.setSubscriber(new Subscriber(subscriberid));
But as #Augusto said, the associations you're having in the session (Slot and Subscriber) are not full objects they contain only their ids. That's why you can't get other fields of these objects.
I am working on a spring mvc app in which I have 2 model classes. Following are my model classes:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
#Entity
#Table(name="Contact")
public class ContactModel {
#Id
#Column(name="contactid")
#GeneratedValue
private int contactId;
#Column(name="contactname")
private String contactName;
#Column(name="contactemail")
private String email;
#Column(name="contactphone")
private String phone;
#ManyToOne
#JoinColumn(name="locationid")
private LocationModel locationModel;
public LocationModel getLocationModel() {
return locationModel;
}
public void setLocationModel(LocationModel locationModel) {
this.locationModel = locationModel;
}
public int getContactId() {
return contactId;
}
public void setContactId(int contactId) {
this.contactId = contactId;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
and LocationModel
import java.util.List;
//import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Cascade;
#Entity
#Table(name="Location")
public class LocationModel {
#Id
#Column(name="locationid")
#GeneratedValue
private int locationId;
#Column(name="locationname")
private String locationName;
#Column(name="locationdesc")
private String locationDescription;
#Column(name="type")
private String locationType;
#Column(name="address")
private String address;
#Column(name="city")
private String city;
#Column(name="state")
private String state;
#Column(name="district")
private String district;
#Column(name="lattitude")
private String lattitude;
#Column(name="longitude")
private String longitude;
#OneToMany(mappedBy = "locationModel")
private List<ContactModel> contactList;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getLattitude() {
return lattitude;
}
public void setLattitude(String lattitude) {
this.lattitude = lattitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getLocationType() {
return locationType;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public void setLocationType(String locationType) {
this.locationType = locationType;
}
public int getLocationId() {
return locationId;
}
public void setLocationId(int locationId) {
this.locationId = locationId;
}
public String getLocationName() {
return locationName;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
public String getLocationDescription() {
return locationDescription;
}
public void setLocationDescription(String locationDescription) {
this.locationDescription = locationDescription;
}
}
On deleting location I want to set location of corresponding contacts to null. I am using following code for this:
public void selLocationToNull(int locationId) throws Exception {
try {
logger.info("deleteContact() begins:");
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("update ContactModel set locationModel=:newLocation where locationModel=:locationId");
query.setParameter("newLocation", null);
query.setParameter("locationId", locationId);
query.executeUpdate();
logger.info("null update query executed...");
} catch (Exception e) {
logger.debug("Error while updating location to null: "
+ e.getMessage());
throw e;
} finally {
}
}
I am getting exception for this:
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.bizmerlin.scm.model.LocationModel.locationId
Caused by: java.lang.IllegalArgumentException: Can not set int field com.bizmerlin.scm.model.LocationModel.locationId to java.lang.Integer
I have getter method for locationId in my LocationModel class.
How can you set a null to a primitive type? It is generally good practice to use wrapper types for fields in your Entity.
#Id
#Column(name="locationid")
#GeneratedValue
private Integer locationId;
You set in the query's where LocationModel and compare it with int. SHould be
Query query = session.createQuery("update ContactModel set locationModel=:newLocation where locationModel.id=:locationId");
instead. Or pass the LocationModel instance rather than id
I have created Three classes- User, UserSubscription and Subscription. I want that users in the UserSubscription table should be referenced by the users existing in the User table. So, how to use mappedBy?
The classes are as follows:
User:
package com.model;
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 javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
#Entity
public class User {
private int userId;
private String password;
private String contact;
private String firstName;
private String lastName;
private String gender;
private String address;
private int age;
private String email;
private String countBooks;
private Set<Language> languages = new HashSet<Language>(0);
private Set<Book> favorites = new HashSet<Book>(0);
#Id
#GeneratedValue
#Column(name="User_Id")
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
#Column(name="Password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name="Contact")
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
#Column(name="First_Name")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name="Last_Name")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name="Gender")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Column(name="Address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name="Age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Column(name="Email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name="Count_Books")
public String getCountBooks() {
return countBooks;
}
public void setCountBooks(String countBooks) {
this.countBooks = countBooks;
}
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name="User_Language", joinColumns = {
#JoinColumn(name = "User_Id", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "Language_Id",
nullable = false, updatable = false) })
public Set<Language> getLanguages() {
return languages;
}
public void setLanguages(Set<Language> languages) {
this.languages = languages;
}
#ManyToMany
#JoinTable(name="User_Favorite", joinColumns = {
#JoinColumn(name = "User_Id", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "Book_Id",
nullable = false, updatable = false) })
public Set<Book> getFavorites() {
return favorites;
}
public void setFavorites(Set<Book> favorites) {
this.favorites = favorites;
}
}
UserSubscription:
package com.model;
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
#Entity
public class UserSubscription {
private int userSubscriptionId;
private Subscription subscription;
private User user;
private Date subscriptionStartDate;
private Date subscriptionEndDate;
private int status;
#Id
#GeneratedValue
#Column(name="User_Subscription_Id")
public int getUserSubscriptionId() {
return userSubscriptionId;
}
public void setUserSubscriptionId(int userSubscriptionId) {
this.userSubscriptionId = userSubscriptionId;
}
#Column(name="Subscription_Id")
public Subscription getSubscription() {
return subscription;
}
public void setSubscription(Subscription subscription) {
this.subscription = subscription;
}
#OneToOne(mappedBy="userId")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name="Subscription_Start_Date")
public Date getSubscriptionStartDate() {
return subscriptionStartDate;
}
public void setSubscriptionStartDate(Date subscriptionStartDate) {
this.subscriptionStartDate = subscriptionStartDate;
}
#Column(name="Subscription_End_Date")
public Date getSubscriptionEndDate() {
return subscriptionEndDate;
}
public void setSubscriptionEndDate(Date subscriptionEndDate) {
this.subscriptionEndDate = subscriptionEndDate;
}
#Column(name="Status")
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
Subscription:
package com.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Subscription {
private int subscriptionId;
private String name;
private int period;
private float fees;
private int noOfBooks;
private int Status;
#Id
#GeneratedValue
public int getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(int subscriptionId) {
this.subscriptionId = subscriptionId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPeriod() {
return period;
}
public void setPeriod(int period) {
this.period = period;
}
public float getFees() {
return fees;
}
public void setFees(float fees) {
this.fees = fees;
}
public int getNoOfBooks() {
return noOfBooks;
}
public void setNoOfBooks(int noOfBooks) {
this.noOfBooks = noOfBooks;
}
public int getStatus() {
return Status;
}
public void setStatus(int status) {
Status = status;
}
}
Exception while executing:
Exception in thread "main" org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne: com.model.User.userId in mappedBy of com.model.UserSubscription.user
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:248)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at com.impetus.model.Check.main(Check.java:92)
In your code, user-user_subscription looks uni-directional. 'mappedby' should be used in bi-directional relationship.
You can use following code in user entity to make it bi-directional with user_subscription.
private UserSubscription userSubscription;
#OneToOne
public User getUserSubscription() {
return userSubscription;
}
Or remove mappedby from user_subscription and make it unidirectional.
Seems you are unsure of what mappedBy is used for or means. Database relationships are one sided; one table will have a foreign key reference to the target table. In JPA, you might map this relationship as a OneToOne and specify the foreign key to use with the #JoinColumn annotation:
#OneToOne(mappedBy="userId")
#JoinColumn(name = "USER_ID")
public User getUser() {
return user;
}
The Join column definition is optional, and if not used JPA will default to using the attribute name with "_" and the target entity's ID name prepended, so "USER_ID" in this case anyway.
Back to the database, because target table is referenced by the source table, this forms another implicit relationship back (the target table's ID can be used to look up the other table's foreign key). In JPA, this can be mapped again as a OneToOne or a OneToMany depending on the cardinality. If it is a OneToOne, you specify that this relationship does not define the foreign key by marking it as mappedBy the other relationship:
#OneToOne(mappedBy="user")
public UserSubscription getUserSubscription() {
return userSubscription;
}
But it is more likely a User will have multiple userSubscriptions:
#OneToMany(mappedBy="user")
public Collection<UserSubscription> getUserSubscriptions () {
return userSubscription ;
}
In both cases, you use the mappedBy to signal that there is a 'user' attribute in the target entity that defines a relationship to this entity and controls the foreign key setting in the database.
You also need to change how your define the UserSubscription->Subscription relationship, as you have defined an #Column on what appears to be a relationship. It should probably be
#OneToOne
#JoinColumn(name="Subscription_Id")
public Subscription getSubscription() {
return subscription;
}
you should have UserSubscription memeber and corrosponding gettes and setters in your User class like below:
private Set<Company> userSubscriptions = new HashSet<Company>(0);
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
public Set<UserSubscription> getUserSubscriptions() {
return this.userSubscriptions ;
}
public void setUserSubscriptions(Set<UserSubscription> userSubscriptions ) {
this.userSubscriptions = userSubscriptions ;
}
and same way you should have user object as memeber in UserSubscription Entity class.
private User user;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
You are doing it wrong
class User {
UserSubscription userSubscription ;
#OneToOne
public UserSubscription getUserSubscription(){
return userSubscription ;
}
public void setUserSubscription(UserSubscription userSubscription ){
this.userSubscription = userSubscription ;
}
}
class UserSubscription {
#OneToOne(mappedBy="userSubscription")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}