JPA/Hibernate persist does not appear to work - java

I'm using JPA (Hibernate implementation) to save objects to the database. Selecting works fine, but for some reason, saving doesn't work. I don't get any errors, but the database doesn't get changed either. This goes for both new entities and existing ones.
EPayment pay = new EPayment();
pay.setAmount(payment.getAmount());
...
pay.setUserByToUserId(receiver);
CompayDAO.get().save(pay);
CompayDAO.save()
public void save(Object ent) {
System.out.println("Persisting: " + ent + " using " + this);
this.em.persist(ent);
}
Console output:
Opening DOA nl.compay.entities.CompayDAO#b124fa
Persisting: nl.compay.entities.EUser#1e2fe5d using nl.compay.entities.CompayDAO#b124fa
Persisting: nl.compay.entities.EUser#30b601 using nl.compay.entities.CompayDAO#b124fa
Persisting: nl.compay.entities.EPayment#ed3b53 using nl.compay.entities.CompayDAO#b124fa
Closing DOA nl.compay.entities.CompayDAO#b124fa
EPayment
package nl.compay.entities;
// Generated 21-mei-2009 12:27:07 by Hibernate Tools 3.2.2.GA
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Payment generated by hbm2java
*/
#Entity
#Table(name = "payment", catalog = "compay")
public class EPayment implements java.io.Serializable {
private static final long serialVersionUID = -2578493336948256566L;
private Integer id;
private EUser userByToUserId;
private EUser userByFromUserId;
private String description;
private float amount;
private String method;
private Date paydate;
public EPayment() {
}
public EPayment(EUser userByToUserId, EUser userByFromUserId, float amount,
Date paydate) {
this.userByToUserId = userByToUserId;
this.userByFromUserId = userByFromUserId;
this.amount = amount;
this.paydate = paydate;
}
public EPayment(EUser userByToUserId, EUser userByFromUserId,
String description, float amount, String method, Date paydate) {
this.userByToUserId = userByToUserId;
this.userByFromUserId = userByFromUserId;
this.description = description;
this.amount = amount;
this.method = method;
this.paydate = paydate;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "to_user_id", nullable = false)
public EUser getUserByToUserId() {
return this.userByToUserId;
}
public void setUserByToUserId(EUser userByToUserId) {
this.userByToUserId = userByToUserId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "from_user_id", nullable = false)
public EUser getUserByFromUserId() {
return this.userByFromUserId;
}
public void setUserByFromUserId(EUser userByFromUserId) {
this.userByFromUserId = userByFromUserId;
}
#Column(name = "description", length = 1024)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "amount", nullable = false, precision = 8)
public float getAmount() {
return this.amount;
}
public void setAmount(float amount) {
this.amount = amount;
}
#Column(name = "method", length = 50)
public String getMethod() {
return this.method;
}
public void setMethod(String method) {
this.method = method;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "paydate", nullable = false, length = 0)
public Date getPaydate() {
return this.paydate;
}
public void setPaydate(Date paydate) {
this.paydate = paydate;
}
}

As Sherkaner mentioned, a save doesn't result in an INSERT or UPDATE directly. You have to flush the session or - better in my opinion - close the unit of work / commit the transaction. You do have transactions?

use #Transactional on your method.....
#Transactional
public void save(Object ent){
.....
.....
}

The program doesn't have to sync with the database right away, have you tried this.em.flush(); somewhere?

Don't think this as bug in Hibernate implementation.This is desired behavior,you would like to have minimum communication with database so Hibernate(or any good ORM framework) will consolidate all your changes and will flush your changes in one go.

Related

Sorting with model reference on PageRequest not working

I am using Spring data PageRequest to search data based on user filter. I need my sort column to be dynamic along with search filters.
However stateMaster.countryMaster.description, stateMaster.description, description code is not working and throws following error.
org.springframework.data.mapping.PropertyReferenceException: No property description, stateMaster found for type CountryMaster! Traversed path: DistrictMaster.stateMaster.countryMaster.
Here's my service code.
String sortColumn = filterJson.getString("sortColumn");
if ("default".equalsIgnoreCase(filterJson.getString("sortColumn"))) {
sortColumn = "stateMaster.countryMaster.description, stateMaster.description, description";
} else {
sortColumn = "description";
}
String sortOrder = filterJson.getString("sortOrder");
Integer maxResult = Integer.parseInt(hbsService.getGeneralConfigValue("adminmaxallowedlisting"));
PageRequest pageRequest = new PageRequest(pageNo, maxResult, Sort.Direction.valueOf(sortOrder), sortColumn);
Page<DistrictMaster> page = districtRepository.findAll(new Specification<DistrictMaster>() {
#Override
public Predicate toPredicate(Root<DistrictMaster> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
if (filterJson.optLong("stateId") != 0) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("stateMaster"), filterJson.optLong("stateId"))));
}
if (!filterJson.optString("status").trim().isEmpty() && !filterJson.optString("status").equals("All")) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("active"), filterJson.optBoolean("status"))));
}
if (!filterJson.optString("value").trim().isEmpty()) {
predicates.add(criteriaBuilder.and(criteriaBuilder.like(criteriaBuilder.lower(root.get("description")), "%" + filterJson.optString("value").toLowerCase() + "%")));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
}, pageRequest);
Here's my model:
package com.agrisk.data.model;
import java.io.Serializable;
import java.util.Set;
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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "tbldistrictmst")
#SequenceGenerator(name = "districtmstseq", allocationSize = 1, sequenceName = "districtmstseq")
public class DistrictMaster extends MakerCheckerBO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5461420398663313529L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "districtmstseq")
#Column(name = "id")
public Long id;
#Column(name = "description")
public String description;
#Column(name = "code")
public String code;
#ManyToOne
#JoinColumn(name = "stateid")
private StateMaster stateMaster;
#Column(name = "active")
public Boolean active;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "districtid")
public Set<TehsilMaster> tehsilMaster;
#Column(name = "villagereferenceid")
private Long villageReferenceId;
public Set<TehsilMaster> getTehsilMaster() {
return tehsilMaster;
}
public void setTehsilMaster(Set<TehsilMaster> tehsilMaster) {
this.tehsilMaster = tehsilMaster;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public StateMaster getStateMaster() {
return stateMaster;
}
public void setStateMaster(StateMaster stateMaster) {
this.stateMaster = stateMaster;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Long getVillageReferenceId() {
return villageReferenceId;
}
public void setVillageReferenceId(Long villageReferenceId) {
this.villageReferenceId = villageReferenceId;
}
}

Join in hibernate with annotaion

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();

org.hibernate.QueryException: duplicate association path for #ManyToOne Criteria

I have two classes which has a relationship between them. These are
com.edfx.adb.persist.Activity:
package com.edfx.adb.persist.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NaturalId;
#javax.persistence.Entity
#Table(name = "ACTIVITY")
public class Activity extends Entity {
#Transient
private static final long serialVersionUID = 4741665931936809028L;
private String activityId;
private String activityName;
private String activityDescription;
private Customer customer;
private ActivityType activityType;
private boolean active;
private Double mandays;
private Double price;
private String manager;
private List<Participation> participations;
public Activity() {
super();
}
#NaturalId
#Column(name = "ACTIVITY_ID", nullable = false)
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
#Lob
#Column(name = "ACTIVITY_NAME", nullable = false)
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
#Lob
#Column(name = "ACTIVITY_DESCRIPTION", nullable = false)
public String getActivityDescription() {
return activityDescription;
}
public void setActivityDescription(String activityDescription) {
this.activityDescription = activityDescription;
}
#ManyToOne
#JoinColumn(name = "CUSTOMER_ID", nullable = false)
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
#ManyToOne
#JoinColumn(name = "ACTIVITY_TYPE_ID", nullable = false)
public ActivityType getActivityType() {
return activityType;
}
public void setActivityType(ActivityType activityType) {
this.activityType = activityType;
}
#Column(name = "ACTIVE", nullable = false)
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
#Column(name = "MANDAYS")
public Double getMandays() {
return mandays;
}
public void setMandays(Double mandays) {
this.mandays = mandays;
}
#Column(name = "PRICE")
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
#Column(name = "CUSTOMER_SIDE_MANAGER")
public String getManager() {
return manager;
}
public void setManager(String manager) {
this.manager = manager;
}
#OneToMany(mappedBy = "activity", fetch = FetchType.LAZY)
#Cascade(CascadeType.SAVE_UPDATE)
public List<Participation> getParticipations() {
return participations;
}
public void setParticipations(List<Participation> participations) {
this.participations = participations;
}
}
com.edfx.adb.persist.ActivityType:
package com.edfx.adb.persist.entity;
import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
#javax.persistence.Entity
#Table(name = "ACTIVITY_TYPE")
public class ActivityType extends Entity {
#Transient
private static final long serialVersionUID = 2322745769010162801L;
private String parent;
private String name;
private String activityId;
public ActivityType() {
}
#Column(name = "PARENT", nullable = false)
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
#Column(name = "NAME", nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "ACTIVITY_ID", nullable = false)
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
}
Both of them extends com.edfx.adb.persist.entity.Entity:
package com.edfx.adb.persist.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;
import org.hibernate.proxy.HibernateProxyHelper;
#MappedSuperclass
public class Entity implements Serializable {
#Transient
private static final long serialVersionUID = 7470288121057059283L;
private Long id;
private Date createTimestamp;
private Date lastUpdateTimestamp;
private Long version;
public Entity() {
super();
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", updatable = false, nullable = false, unique = true)
public Long getId() {
return id;
}
#SuppressWarnings("unused")
private void setId(Long id) {
this.id = id;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CREATE_TIMESTAMP")
public Date getCreateTimestamp() {
return createTimestamp;
}
public void setCreateTimestamp(Date createTimestamp) {
this.createTimestamp = createTimestamp;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "LAST_UPDATE_TIMESTAMP")
public Date getLastUpdateTimestamp() {
return lastUpdateTimestamp;
}
public void setLastUpdateTimestamp(Date lastUpdateTimestamp) {
this.lastUpdateTimestamp = lastUpdateTimestamp;
}
#Version
#Column(name = "VERSION")
public Long getVersion() {
return version;
}
#SuppressWarnings("unused")
private void setVersion(Long version) {
this.version = version;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
return prime * result + ((getId() == null) ? super.hashCode() : getId().hashCode());
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!getClass().equals(HibernateProxyHelper.getClassWithoutInitializingProxy(obj))) {
return false;
}
final Entity other = (Entity) obj;
if (getId() != other.getId()) {
if (getId() == null) {
return false;
}
if (!getId().equals(other.getId())) {
return false;
}
}
return true;
}
}
Now I am using Primefaces datatable to show a List<Activity> in which I have filtering on the field name of ActivityType. ActivityType is associated with Activity by #ManyToOne relationship.
For filtering the List<Activity> I am using:
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);
criteria.createCriteria("activityType").add(Restrictions.like("name", value.toString(), MatchMode.START));
I am getting:
null: org.hibernate.QueryException: duplicate association path: activityType
at org.hibernate.loader.criteria.CriteriaQueryTranslator.createAssociationPathCriteriaMap(CriteriaQueryTranslator.java:172) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.loader.criteria.CriteriaQueryTranslator.<init>(CriteriaQueryTranslator.java:111) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:84) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1602) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at com.edfx.adb.dao.ActivityDao.loadActivities(ActivityDao.java:54) [classes:]
at com.edfx.adb.service.ActivityService.loadActivities(ActivityService.java:101) [classes:]
This error is not showing always and never after the first load. After filtering the table for 5-6 time, I am having this error.
I am worried that if the mapping and the criteria is right or not. Any suggestion would be very helpful.
I think you need to provide an alias, so you should change your code this way:
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);
criteria.createCriteria("activityType", "at")
.add(
Restrictions.like("at.name", value.toString(), MatchMode.START));

Hibernate, display join left results in Spring

I'm learning Spring and Hibernate and i have small but quite important problem.
I want to get data from database:
Query query = session.createSQLQuery("SELECT * FROM pool a LEFT JOIN pool_question b on a.id = b.poolid");
and then sent results as list to jsp file from my controller
model.addAttribute("pools", pool);
My database is quite simple:
pool is:
id name slug date_create deactivation_date creator_id active
and poolquestion is
id poolid answer order question
The problem is, that when i'm trying to make a loop in jsp:
<c:forEach items="${pools}" var="pool">
<td><c:out value="${pool.name}" /></td>
</c:forEach>
tomcat displays me error.
When i check my query in phpmyadmin the result is ok.
The trick is, that when i do query like this:
Query query = session.createQuery("FROM Pool");
The results in jsp are displayed properly.
Could enyone help me how to display result of this query in jsp?
My Pool.java is:
package com.pool.app.domain;
// Generated 2011-12-20 12:45:22 by Hibernate Tools 3.4.0.CR1
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Pool generated by hbm2java
*/
#Entity
#Table(name = "pool", catalog = "pool")
public class Pool implements java.io.Serializable {
private Integer id;
private String name;
private String slug;
private Date dateCreate;
private Date deactivationDate;
private int creatorId;
private int active;
private Set<PoolQuestion> poolQuestions = new HashSet<PoolQuestion>(0);
public Pool() {
}
public Pool(String name, String slug, Date dateCreate,
Date deactivationDate, int creatorId, int active) {
this.name = name;
this.slug = slug;
this.dateCreate = dateCreate;
this.deactivationDate = deactivationDate;
this.creatorId = creatorId;
this.active = active;
}
public Pool(String name, String slug, Date dateCreate,
Date deactivationDate, int creatorId, int active,
Set<PoolQuestion> poolQuestions) {
this.name = name;
this.slug = slug;
this.dateCreate = dateCreate;
this.deactivationDate = deactivationDate;
this.creatorId = creatorId;
this.active = active;
this.poolQuestions = poolQuestions;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "name", nullable = false, length = 200)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "slug", nullable = false, length = 200)
public String getSlug() {
return this.slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "date_create", nullable = false, length = 19)
public Date getDateCreate() {
return this.dateCreate;
}
public void setDateCreate(Date dateCreate) {
this.dateCreate = dateCreate;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "deactivation_date", nullable = false, length = 19)
public Date getDeactivationDate() {
return this.deactivationDate;
}
public void setDeactivationDate(Date deactivationDate) {
this.deactivationDate = deactivationDate;
}
#Column(name = "creator_id", nullable = false)
public int getCreatorId() {
return this.creatorId;
}
public void setCreatorId(int creatorId) {
this.creatorId = creatorId;
}
#Column(name = "active", nullable = false)
public int getActive() {
return this.active;
}
public void setActive(int active) {
this.active = active;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pool")
public Set<PoolQuestion> getPoolQuestions() {
return this.poolQuestions;
}
public void setPoolQuestions(Set<PoolQuestion> poolQuestions) {
this.poolQuestions = poolQuestions;
}
}
and PoolQuestion.java is:
package com.pool.app.domain;
// Generated 2011-12-20 12:45:22 by Hibernate Tools 3.4.0.CR1
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* PoolQuestion generated by hbm2java
*/
#Entity
#Table(name = "pool_question", catalog = "pool")
public class PoolQuestion implements java.io.Serializable {
private Integer id;
private Pool pool;
private String answer;
private int order;
private String question;
public PoolQuestion() {
}
public PoolQuestion(Pool pool, String answer, int order) {
this.pool = pool;
this.answer = answer;
this.order = order;
}
public PoolQuestion(Pool pool, String answer, int order, String question) {
this.pool = pool;
this.answer = answer;
this.order = order;
this.question = question;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "poolid", nullable = false)
public Pool getPool() {
return this.pool;
}
public void setPool(Pool pool) {
this.pool = pool;
}
#Column(name = "answer", nullable = false, length = 500)
public String getAnswer() {
return this.answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
#Column(name = "order", nullable = false)
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
#Column(name = "question", length = 500)
public String getQuestion() {
return this.question;
}
public void setQuestion(String question) {
this.question = question;
}
}
And the main question - how the HQL query should looks, becouse query like this:
Query query = session.createQuery("From Pool as p left join fetch p.id as s");
doesn't works for me.
Without the exception it's hard to know exactly what's going wrong. However, have a read of:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html
I think you're problem is that you're using createSQLQuery instead of createQuery. Ie you're using standard SQL instead of HQL. To get you started, try changing your query to:
SELECT a.* FROM pool a LEFT JOIN ...
and make a call to .addEntity(Pool.class), ie session.createSQLQuery("<use above SQL>").addEntity(Pool.class);
Good luck.
Query query = session.createQuery("from Pool");
Is an HQL query, it will give you a list of Objects (Pool), so there is no problem to use :
<c:forEach items="${pools}" var="pool">
<td><c:out value="${pool.name}" /></td>
</c:forEach>
when you use an SQL query, it's different, you will not get a list of objects (you have to add some code and transformations to get a list of pools).
Here an example :
#SuppressWarnings({ "unchecked", "rawtypes" })
public List<Pool> findPools()
{
final String query = "select a.id as idAlias, a.name as nameAlias from pool a ....";
List<Pool> list = (List<Pool>) getHibernateTemplate().execute(new HibernateCallback()
{
public Object doInHibernate(Session session) throws HibernateException
{
SQLQuery sqlQuery = session.createSQLQuery(query);
return prepareQueryFind(sqlQuery).list();
}
});
return list;
}
Here i suppose you have a constructor like :
public Pool(Integer id, String name);
/** Getters and Setters **/
if you are using Hibernate version >= 3.2
#SuppressWarnings("deprecation")
private Query prepareQueryFind(SQLQuery query)
{
return query
.addScalar("idAlias", Hibernate.INTEGER)
.addScalar("nameAlias", Hibernate.STRING)
.setResultTransformer(Transformers.aliasToBean(Pool.class));
}
Now you can call fidpools like this :
List<Pool> poolList = poolDao.findPools();
When using Hibernate You don't usually want to use native SQL but rather HQL.
If you are using native query createSQLQuery then you have to specify explicitly How should be values mapped to your POJO or specify scalars - see hibernate documentation.
And why are you using this query in the first place? Can't you obtain the poolquestion values from some association mapping of Pool class? That's the whole point of Hibernate.
Let me be more clear.
First forget the join in query. You don't need it. You want POJO instances no some crazy result set of outer join.
Query all Pool data as you did Query query = session.createQuery("FROM Pool");
Get list containing Pool instances representing your data List<Pool> pools = (List<Pool>) query.list();
Now you have it. All associated data are obtained by Hibernate lazily when you ask for them - pool.getPoolQuestions();
You can try this:
Query hqlQuery = session.createQuery("from Pool as P left join P.poolQuestion");
You can look for more here.
Some advice:
If you are using Hibernate and Spring, why you don't use getHibernateTemplate() to get your data from tables? In this case you can use:
List<Pool> result = (List<Pool>) getHibernateTemplate().find("from Pool");
and all you data will be in this result.
For more details you can follow this example.
Please check if I'm right, because I haven't tested/simulated it.

Hibernate related object not hydrated

Please see code below. DeviceDAO, Device, and Mobileuser are hibernate generated objects. the process works until i get to the second "if" conditional where I call mobileUser.getPin(). The problem is that mobileUser's properties (such as pin) are null. The values exist in the DB, but they area null, so my calls throw null pointer exceptions. Mobileuser's properties haven't been hydrated by hibernate. Any help is appreciated. Thanks.
DeviceDAO deviceDao = new DeviceDAO();
List<Device> devices = deviceDao.findByUdid(requestTokenModel.getUdid());
if(!devices.isEmpty())
{
Device device = devices.get(0);
Mobileuser mobileUser =device.getMobileuser();
if(mobileUser.getPin().contentEquals(requestTokenModel.getPiin()) && mobileUser.getIsactive() == "Y")
{
//omitted
}
}
UPDATE
Here's some more information as requested:
I am using MyEclipse Hibernate Reverse Engineering to generated data objects and DAO objects. Using annotations for mapping.
Here is Mobileuser.java
package com.myeclipse.hibernate;
import java.util.Date;
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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
/**
* Mobileuser entity. #author MyEclipse Persistence Tools
*/
#Entity
#Table(name = "MOBILEUSER", schema = "WARPVALID")
public class Mobileuser implements java.io.Serializable {
// Fields
private Integer mobileuserid;
private Servicetype servicetype;
private String lastname;
private String username;
private String firstname;
private String organization;
private String piin;
private String isactive;
private Date createdate;
private Date modifydate;
private String email;
private String isaccepted;
private Set<Registration> registrations = new HashSet<Registration>(0);
private Set<Device> devices = new HashSet<Device>(0);
// Constructors
/** default constructor */
public Mobileuser() {
}
/** minimal constructor */
public Mobileuser(String lastname, String username, String firstname,
String piin, String isactive, Date createdate, Date modifydate,
String isaccepted) {
this.lastname = lastname;
this.username = username;
this.firstname = firstname;
this.piin = piin;
this.isactive = isactive;
this.createdate = createdate;
this.modifydate = modifydate;
this.isaccepted = isaccepted;
}
/** full constructor */
public Mobileuser(Servicetype servicetype, String lastname,
String username, String firstname, String organization,
String piin, String isactive, Date createdate, Date modifydate,
String email, String isaccepted, Set<Registration> registrations,
Set<Device> devices) {
this.servicetype = servicetype;
this.lastname = lastname;
this.username = username;
this.firstname = firstname;
this.organization = organization;
this.piin = piin;
this.isactive = isactive;
this.createdate = createdate;
this.modifydate = modifydate;
this.email = email;
this.isaccepted = isaccepted;
this.registrations = registrations;
this.devices = devices;
}
// Property accessors
#GenericGenerator(name = "generator", strategy = "increment")
#Id
#GeneratedValue(generator = "generator")
#Column(name = "MOBILEUSERID", unique = true, nullable = false, precision = 9, scale = 0)
public Integer getMobileuserid() {
return this.mobileuserid;
}
public void setMobileuserid(Integer mobileuserid) {
this.mobileuserid = mobileuserid;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "SERVICETYPEID")
public Servicetype getServicetype() {
return this.servicetype;
}
public void setServicetype(Servicetype servicetype) {
this.servicetype = servicetype;
}
#Column(name = "LASTNAME", nullable = false, length = 30)
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
#Column(name = "USERNAME", nullable = false, length = 20)
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "FIRSTNAME", nullable = false, length = 30)
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
#Column(name = "ORGANIZATION", length = 50)
public String getOrganization() {
return this.organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
#Column(name = "PIIN", nullable = false, length = 10)
public String getPiin() {
return this.piin;
}
public void setPiin(String piin) {
this.piin = piin;
}
#Column(name = "ISACTIVE", nullable = false, length = 1)
public String getIsactive() {
return this.isactive;
}
public void setIsactive(String isactive) {
this.isactive = isactive;
}
#Temporal(TemporalType.DATE)
#Column(name = "CREATEDATE", nullable = false, length = 7)
public Date getCreatedate() {
return this.createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
#Temporal(TemporalType.DATE)
#Column(name = "MODIFYDATE", nullable = false, length = 7)
public Date getModifydate() {
return this.modifydate;
}
public void setModifydate(Date modifydate) {
this.modifydate = modifydate;
}
#Column(name = "EMAIL", length = 50)
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "ISACCEPTED", nullable = false, length = 1)
public String getIsaccepted() {
return this.isaccepted;
}
public void setIsaccepted(String isaccepted) {
this.isaccepted = isaccepted;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "mobileuser")
public Set<Registration> getRegistrations() {
return this.registrations;
}
public void setRegistrations(Set<Registration> registrations) {
this.registrations = registrations;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "mobileuser")
public Set<Device> getDevices() {
return this.devices;
}
public void setDevices(Set<Device> devices) {
this.devices = devices;
}
}
And this is Device.java:
package com.myeclipse.hibernate;
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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
/**
* Device entity. #author MyEclipse Persistence Tools
*/
#Entity
#Table(name = "DEVICE", schema = "WARPVALID")
public class Device implements java.io.Serializable {
// Fields
private Integer deviceid;
private Mobileuser mobileuser;
private String udid;
private String applicationversion;
private String dataversion;
private Set<Authentication> authentications = new HashSet<Authentication>(0);
// Constructors
/** default constructor */
public Device() {
}
/** minimal constructor */
public Device(Mobileuser mobileuser, String udid) {
this.mobileuser = mobileuser;
this.udid = udid;
}
/** full constructor */
public Device(Mobileuser mobileuser, String udid,
String applicationversion, String dataversion,
Set<Authentication> authentications) {
this.mobileuser = mobileuser;
this.udid = udid;
this.applicationversion = applicationversion;
this.dataversion = dataversion;
this.authentications = authentications;
}
// Property accessors
#GenericGenerator(name = "generator", strategy = "increment")
#Id
#GeneratedValue(generator = "generator")
#Column(name = "DEVICEID", unique = true, nullable = false, precision = 9, scale = 0)
public Integer getDeviceid() {
return this.deviceid;
}
public void setDeviceid(Integer deviceid) {
this.deviceid = deviceid;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "MOBILEUSERID", nullable = false)
public Mobileuser getMobileuser() {
return this.mobileuser;
}
public void setMobileuser(Mobileuser mobileuser) {
this.mobileuser = mobileuser;
}
#Column(name = "UDID", nullable = false, length = 20)
public String getUdid() {
return this.udid;
}
public void setUdid(String udid) {
this.udid = udid;
}
#Column(name = "APPLICATIONVERSION", length = 20)
public String getApplicationversion() {
return this.applicationversion;
}
public void setApplicationversion(String applicationversion) {
this.applicationversion = applicationversion;
}
#Column(name = "DATAVERSION", length = 20)
public String getDataversion() {
return this.dataversion;
}
public void setDataversion(String dataversion) {
this.dataversion = dataversion;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "device")
public Set<Authentication> getAuthentications() {
return this.authentications;
}
public void setAuthentications(Set<Authentication> authentications) {
this.authentications = authentications;
}
}
Mobileuser.hbm has a property named "piin" while your Mobileuser class has a method getPin(). Is it possible that one of these is a typo? They should match, assuming that they are meant to represent the same information. As should the setter, setPin(String) or setPiin(String) whichever it should be.
If the db has a column "piin", you can change the mapping to map property pin to column piin, though this means you won't be able to regenerate the mapping from the db in the future.
Scares me when this happens, but I just got back from lunch and now it's working correctly. Didn't make any changes from before, but it's happy now. No idea what was causing it.
Thanks for the debugging help #Corey.

Categories