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;
}
}
Related
I've been going on a hobby project of mine for a couple of weeks that is basically a quiz assistant. What it does is after a test, I'm going to check what questions and answers I got right by inputting part of the question text and retrieving the category (e.g.: Chemistry), the questions related to my search queue (e.g.: NaCl, DNA, pH) and the answers related to those questions.
All of them are stored in a MySQL database, in this manner: Database Scheme.
When I first started, I was using an EAGER way of fetching all the records (since there weren't as many as today). However, today I'm counting a large collection of questions and answers and can't seem to get the lazy loading to be working.
Considering the following simple code:
Main.java
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.mybizname.quizassistant.database.dao.impl.CategoryDaoImpl;
import org.mybizname.quizassistant.database.entity.impl.CategoryEntityImpl;
import org.mybizname.quizassistant.database.entity.impl.QuestionEntityImpl;
import org.mybizname.quizassistant.database.utilities.HibernateUtil;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
List<CategoryEntityImpl> categories = new CategoryDaoImpl().fetchAll();
categories.forEach((category) -> {
Set<QuestionEntityImpl> questions = category.getQuestions();
});
HibernateUtil.shutdown();
System.exit(0);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
}
HibernateUtil.java
import java.util.HashMap;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import org.mybizname.quizassistant.database.entity.impl.AnswerEntityImpl;
import org.mybizname.quizassistant.database.entity.impl.CategoryEntityImpl;
import org.mybizname.quizassistant.database.entity.impl.QuestionEntityImpl;
public class HibernateUtil {
private static StandardServiceRegistry standardServiceRegistry;
private static SessionFactory sessionFactory;
static {
StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
Map<String, String> hibernateConfiguration = new HashMap<>();
hibernateConfiguration.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
hibernateConfiguration.put(Environment.DRIVER, "com.mysql.jdbc.Driver");
hibernateConfiguration.put(Environment.URL, "jdbc:mysql://localhost:3306/quiz_assistant");
hibernateConfiguration.put(Environment.USER, "root");
hibernateConfiguration.put(Environment.PASS, "pwd");
hibernateConfiguration.put(Environment.QUERY_TRANSLATOR, "org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory");
hibernateConfiguration.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "org.hibernate.context.internal.ThreadLocalSessionContext");
hibernateConfiguration.put(Environment.SHOW_SQL, "true");
hibernateConfiguration.put(Environment.FORMAT_SQL, "true");
standardServiceRegistryBuilder.applySettings(hibernateConfiguration);
standardServiceRegistry = standardServiceRegistryBuilder.build();
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
metadataSources.addAnnotatedClass(CategoryEntityImpl.class);
metadataSources.addAnnotatedClass(QuestionEntityImpl.class);
metadataSources.addAnnotatedClass(AnswerEntityImpl.class);
Metadata metadata = metadataSources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session openSession() {
return sessionFactory.openSession();
}
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
public static void shutdown() {
if (sessionFactory != null) {
StandardServiceRegistryBuilder.destroy(standardServiceRegistry);
}
}
}
GenericEntity.java
import java.io.Serializable;
import java.util.Date;
public interface GenericEntity extends Serializable {
public Long getId();
public void setId(Long id);
public Date getRegistrationTimestamp();
public void setRegistrationTimestamp(Date registrationTimestamp);
}
AbstractGenericEntity.java
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
public abstract class AbstractGenericEntity implements GenericEntity {
#Override
abstract public Long getId();
#Override
abstract public void setId(Long id);
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "registrationTimestamp", length = 19)
protected Date registrationTimestamp;
#Override
public Date getRegistrationTimestamp() {
return this.registrationTimestamp;
}
#Override
public void setRegistrationTimestamp(Date registrationTimestamp) {
this.registrationTimestamp = registrationTimestamp;
}
}
GenericDao.java
import java.util.List;
public interface GenericDao<T> {
public void persist(T entity);
public void update(T entity);
public void remove(T entity);
public void removeAll();
public List<T> fetchAll();
public List<T> fetchAllByExample(T entity);
public T findById(Long id);
public Class<T> getType();
}
AbstractGenericDao.java
import java.lang.reflect.ParameterizedType;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.mybizname.quizassistant.database.utilities.HibernateUtil;
public abstract class AbstractGenericDao<T> implements GenericDao<T> {
private final Class<T> type;
public AbstractGenericDao() {
type = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
#Override
public void persist(T entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void update(T entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void remove(T entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void removeAll() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public List<T> fetchAll() {
List<T> entities;
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getType());
criteriaQuery.from(getType());
entities = session.createQuery(criteriaQuery).getResultList();
transaction.commit();
return entities;
}
#Override
public List<T> fetchAllByExample(T entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public T findById(Long id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public Class<T> getType() {
return type;
}
}
CategoryEntityImpl
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 javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.mybizname.quizassistant.database.entity.AbstractGenericEntity;
#Entity
#Table(name = "category", catalog = "quiz_assistant", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
public class CategoryEntityImpl extends AbstractGenericEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
#Column(name = "name", unique = true, nullable = false)
private String name;
#Column(name = "shortDescription")
private String shortDescription;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
private Set<QuestionEntityImpl> questions = new HashSet<>();
#OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
private Set<AnswerEntityImpl> answers = new HashSet<>();
public CategoryEntityImpl() {
}
public CategoryEntityImpl(String name, Date registrationTimestamp) {
this.name = name;
this.registrationTimestamp = registrationTimestamp;
}
public CategoryEntityImpl(String name, String shortDescription, Date registrationTimestamp, Set<QuestionEntityImpl> questions, Set<AnswerEntityImpl> answers) {
this.name = name;
this.shortDescription = shortDescription;
this.registrationTimestamp = registrationTimestamp;
this.questions = questions;
this.answers = answers;
}
#Override
public Long getId() {
return this.id;
}
#Override
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getShortDescription() {
return this.shortDescription;
}
public void setShortDescription(String shortDescription) {
this.shortDescription = shortDescription;
}
public Set<QuestionEntityImpl> getQuestions() {
return this.questions;
}
public void setQuestions(Set<QuestionEntityImpl> questions) {
this.questions = questions;
}
public Set<AnswerEntityImpl> getAnswers() {
return this.answers;
}
public void setAnswers(Set<AnswerEntityImpl> answers) {
this.answers = answers;
}
}
QuestionEntityImpl
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 javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.mybizname.quizassistant.database.entity.AbstractGenericEntity;
#Entity
#Table(name = "question", catalog = "quiz_assistant")
public class QuestionEntityImpl extends AbstractGenericEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "categoryId", nullable = false)
private CategoryEntityImpl category;
#Column(name = "identifier", nullable = false)
private String identifier;
#Column(name = "text", nullable = false)
private String text;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "question")
private Set<AnswerEntityImpl> answers = new HashSet<>();
public QuestionEntityImpl() {
}
public QuestionEntityImpl(CategoryEntityImpl category, String identifier, String text, Date registrationTimestamp) {
this.category = category;
this.identifier = identifier;
this.text = text;
this.registrationTimestamp = registrationTimestamp;
}
public QuestionEntityImpl(CategoryEntityImpl category, String identifier, String text, Date registrationTimestamp, Set<AnswerEntityImpl> answers) {
this.category = category;
this.identifier = identifier;
this.text = text;
this.registrationTimestamp = registrationTimestamp;
this.answers = answers;
}
#Override
public Long getId() {
return this.id;
}
#Override
public void setId(Long id) {
this.id = id;
}
public CategoryEntityImpl getCategory() {
return this.category;
}
public void setCategory(CategoryEntityImpl category) {
this.category = category;
}
public String getIdentifier() {
return this.identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
public Set<AnswerEntityImpl> getAnswers() {
return this.answers;
}
public void setAnswers(Set<AnswerEntityImpl> answers) {
this.answers = answers;
}
}
AnswerEntityImpl
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.ManyToOne;
import javax.persistence.Table;
import org.mybizname.quizassistant.database.entity.AbstractGenericEntity;
#Entity
#Table(name = "answer", catalog = "quiz_assistant")
public class AnswerEntityImpl extends AbstractGenericEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "categoryId", nullable = false)
private CategoryEntityImpl category;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "questionId", nullable = false)
private QuestionEntityImpl question;
#Column(name = "identifier", nullable = false)
private String identifier;
#Column(name = "text", nullable = false)
private String text;
public AnswerEntityImpl() {
}
public AnswerEntityImpl(CategoryEntityImpl category, QuestionEntityImpl question, String identifier, String text, Date registrationTimestamp) {
this.category = category;
this.question = question;
this.identifier = identifier;
this.text = text;
this.registrationTimestamp = registrationTimestamp;
}
#Override
public Long getId() {
return this.id;
}
#Override
public void setId(Long id) {
this.id = id;
}
public CategoryEntityImpl getCategory() {
return this.category;
}
public void setCategory(CategoryEntityImpl category) {
this.category = category;
}
public QuestionEntityImpl getQuestion() {
return this.question;
}
public void setQuestion(QuestionEntityImpl question) {
this.question = question;
}
public String getIdentifier() {
return this.identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
}
POM Dependencies:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
</dependencies>
There are still CategoryDaoImpl.java, QuestionDaoImpl.java and AnswerDaoImpl.java which are just empty and simply extend AbstractGenericDao.java.
Now, in Main.java, I retrieve the list of categories from the database:
List<CategoryEntityImpl> categories = new CategoryDaoImpl().fetchAll();
And then, when I am trying to loop thru them via:
categories.forEach((category) -> {
Set<QuestionEntityImpl> questions = category.getQuestions();
});
I get the following:
Exception in thread "AWT-EventQueue-0" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.mybizname.quizassistant.database.entity.impl.CategoryEntityImpl.questions, could not initialize proxy - no Session
The only workaround I found so far is a long and not so clever looking hack. Instead of the loop from above, I have to do this:
categories.forEach((category) -> {
System.out.println(category.getName());
Session session = HibernateUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
session.lock(category, LockMode.NONE);
Set<QuestionEntityImpl> questions = category.getQuestions();
questions.forEach((question) -> {
System.out.println("\t" + question.getText());
});
tx.commit();
});
I know this kind of questions go far, far back, but trust me that I have tried anything I could find on the web and the above example is the only solution I found that works. Maybe I am mistaken somewhere? I would do that, just that it doesn't seem right to have to rewrite the same piece of code over and over again for every view I have and every time I need to refresh some data.
Some help would be appreciated.
Thank you in advance.
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();
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 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));
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.