Hibernate : How to get predefined object passing a String value through parameters - java

I used following method to get predefined object .
public Patient getUserNameAndPassword(String username, Session session) {
Patient patient=(Patient)session.get(Patient.class,username);
return patient;
}
After execute this method , following exception was generated .
org.hibernate.TypeMismatchException: Provided id of the wrong type for class beans.Patient. Expected: class java.lang.Integer, got class java.lang.String
PatientService.java
public class PatientService {
private static PatientDAOInterface patientDAOInterface;
public PatientService() {
patientDAOInterface = new PatientDAOImpl();
}
public Session getSession() {
Session session = patientDAOInterface.openCurrentSession();
return session;
}
public Transaction getTransaction(Session session) {
return patientDAOInterface.openTransaction(session);
}
public Patient getUserNameAndPassword(String username){
Session session = patientDAOInterface.openCurrentSession();
Transaction transaction = null;
Patient patient=new Patient();
try{
transaction = patientDAOInterface.openTransaction(session);
patient=patientDAOInterface.getUserNameAndPassword(username, session);
transaction.commit();
}catch(Exception ex){
ex.printStackTrace();
}finally{
session.close();
}
return patient;
}
}
PatientDAOInterface .java
public interface PatientDAOInterface
{
public Patient getUserNameAndPassword(String username,Session session);
public Session openCurrentSession();
public Transaction openTransaction(Session session);
}
PatientDAOImpl.java
public class PatientDAOImpl implements PatientDAOInterface {
#Override
public Patient getUserNameAndPassword(String username, Session session) {
Patient patient=(Patient)session.get(Patient.class,username);
return patient;
}
private static final SessionFactoryBuilder sessionFactoryBuilder = SessionFactoryBuilder.getInstance();
#Override
public Session openCurrentSession() {
Session currentSession = sessionFactoryBuilder.getSessionFactory().openSession();
return currentSession;
}
#Override
public Transaction openTransaction(Session session) {
Transaction beginTransaction = session.beginTransaction();
return beginTransaction;
}
}
I have mentioned my works above.
Actually , I want to pass a String through parameters and get a Patient object.
I am familiar with passing an Integer instead of a String. But I have no idea about this .
Have any ideas ?

You want to find a Patient by his username? Because here you are trying to find him by his ID and you are passing a String representing username. You should write your own query/criteria for getting a Patient by username. Something like this:
Criteria criteria = session.createCriteria(Patient.class);
criteria.add(Restrictions.eq("username", username);
List<Patient> patients = criteria.list();
Or query version:
String hql = "FROM Patient p WHERE p.username = "+username;
Query query = session.createQuery(hql);
List patients = query.list();

I found a answer to the problem.
public Patient getUserNameAndPassword(String username, Session session) {
Query query=session.createQuery("from Patient where user_name= :username");
query.setParameter("username", username);
List list = query.list();
Patient patient=(Patient) list.get(0);
return patient;
}
This is worked for me .
Thanks.

Related

How to show information about an entity?

I have a problem. After clicking on the "create order" button, the user is redirected to the URL: "localhost:8080/currentorder/{id}" After visiting this URL, the user should see order.text.
Attempts to solve: In the DAO, I create a method that, by the ID passed from the controller, looks for an order in HQL:
public List show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("from Order where id = :id");
query.setParameter("id", id);
List result = query.getResultList();
session.getTransaction().commit();
return result;
}
}
But as you understand, after that, the timelif could not display anything (I mean order.getStatus()) Now I still think that I need to search the database and return an object, but how? help me please
My code:
Controller
#PostMapping("/")
public String createOrder (#ModelAttribute("order") Orderdao orderdao, String text, Model model, RedirectAttributes redirectAttributes){
orderdao.createOrder(text);
redirectAttributes.addAttribute("id", orderdao.checkLastOrder());
return "redirect:/currentorders/{id}";
}
#GetMapping("/currentorders/{id}")
public String showOrder (#PathVariable("id") Long id, Orderdao orderdao, Model model, Order order){
model.addAttribute("currentOrder", orderdao.show(id));
return "order";
}
Entity
#Entity
#Table(name = "orders")
public class Order implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String text;
private String customer;
private int status;
public Order(String text, String customer, int status) {
this.text = text;
this.customer = customer;
this.status = status;
}
public Order(String customer) {
this.customer = customer;
}
public Order(){
}
//Getters and setters
Method:
public Order show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("from Order where id = :id");
query.setParameter("id", id);
List result = (List) query.getSingleResult();
session.getTransaction().commit();
return (Order) session.save(result);
}
}
I am missing your code for orderDao.create, but usually you would have a service class (annotated with Springs #Service annotation), which is injected to the controller and which is called to create the entity. You can make this service method return the ID of the just created entity. It could hence be something like public Long createOrder(OrderDao orderDao). Inside there, after calling repository.save(entity), the entity will already have the ID set (try to verify yourself with debugger: Set a breakpoint to the line before you save the entity and check the ID is null, then go one step forward and see that after save, the ID is set).
My answer:
public Order show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("select text from Order where id = :id");
query.setParameter("id", id);
String result = (String) query.getSingleResult();
session.getTransaction().commit();
session.close();
return new Order(result, "adsfreger", 1);
}
}

Special select query is not working in my spring boot application

Repository Class:
#Repository // This my architecture repository class.
public class UserRepositoryImp implements UserRepository {
private EntityManager entityManager;
#Autowired
public UserRepositoryImp(EntityManager entityManager) {
this.entityManager = entityManager;
}
private static final String MY_SQL_COUNT_EMAIL =
"SELECT count(e) FROM User e WHERE e.email=:email "; // This is hibernate query.
#Override
public Integer getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
TypedQuery<Integer> query = session.createQuery(MY_SQL_COUNT_EMAIL, null);
query.setParameter("email", email); // This is return count in database check database
// .. if you email this database passing already exist this email but your count zero created new email.
return query.executeUpdate();
}
}
Service Class:
#Service
#Transactional
public class UserServiceImp implements UserService {
#Autowired
UserRepository userRepository;
#Override
public User validateUser(String email, String password) throws EtAuthException {
return null;
}
#Override
public User registerUser(User user) throws EtAuthException {
Pattern pattern = Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2, 6} $ "); // This regex.
if (pattern.matcher(user.getEmail()).matches()) {
throw new EtAuthException("Invalid email format"); // This is check email regex.
}
Integer count = userRepository.getCountByEmail(user.getEmail()); // This is my method
// .. count email in database and repository methods
if (count > 0) {
throw new EtAuthException("Email already in use");
}
Integer userId = userRepository.create(user);
return userRepository.findById(userId);
}
}
Postman Error:
Cannot invoke "java.lang.Class.isAssignableFrom(java.lang.Class)"
because "resultClass" is null"
Problem:
My problem is actually. I want to write a query to hibernated but for some reason it doesn't work. For such operations in spring boot, ie typing a query, for example polling email, put delete add and updated, how do I do it? I need to query me. I can't solve this problem.
You are calling executeUpdate() for a select query. Try using getSingleResult() instead.
#Override
public long getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = session.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}
OR
#Override
public long getCountByEmail(String email) {
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = entityManager.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}

Display data from database using hibernate

I am new in hibernate and I am struggling with a problem. I want to display a list of objects to a .XHTML page using JSF. But I don't know why, I lose the data on the way. Even though the method from DAO returns a list of objects from database (I saw it by doing debug) when I try to assign that list to a list of users from another class I loose that data and the list from DAO becomes null. So there are no results in GUI from my datatable.
public class UsersBean {
private List<User> allUsers;
public UsersBean() {
init();
}
private void init() {
UsersController.doInitialise(allUsers);
}
// getters, setters
}
public class UsersController {
public static void doInitialise(List<User> users) {
users = new ArrayList<User>();
UserDao userDao = new UserDaoImpl();
users = userDao.getAllEnities();
System.out.println(users.toString());
}
}
public class UserDaoImpl{
#Override
public List<User> getAllEnities() {
List<User> users= null;
Session session = null;
Transaction transaction = null;
try {
session = sessionFactory.openSession();
transaction = session.beginTransaction();
org.hibernate.query.Query query = session.createQuery("from User");
users= query.list();
transaction.commit();
} finally {
session.close();
}
return users;
}
}
If you want to modify the content of the original list, don't assign another list object to it, this will have no effect.
Instead, just alter the content directly, i.e :
public static void doInitialise(List<User> users) {
UserDao userDao = new UserDaoImpl();
users.addAll(userDao.getAllEnities());
System.out.println(users.toString());
}
You are not assigning the value of allUsers into your UsersBean, probably that's why is not working. To have it working, refactor the doInitialise to return a List<User>, then, in the UsersBean, just assign the users.
class UsersBean {
private List<User> allUsers;
public UsersBean() {
init();
}
private void init() {
this.allUsers = UsersController.doInitialise();
}
}
public class UsersController {
public static List<User> doInitialise() {
UserDao userDao = new UserDaoImpl();
return userDao.getAllEnities();
}
}

Trying to test the existence of a record using hibernate 4

I have an addEmployee webservice in the Spring 4 controller as shown in the code which is accepting emp_name and definition.
The insertion in the database table is happening using Hibernate 4 when the insertIntegertype method is called.
#RequestMapping(value="/addEmployee", method=RequestMethod.GET)
public String addEmployee
(
#RequestParam(value="name", defaultValue="") String emp_name,
#RequestParam(value="definition", defaultValue="") String definition
)
{ int emp_id = 0;
try {
EmpDao empDao = (EmpDao)context.getBean("empDao");
Emp empInsert = new Emp();
empInsert.setName(emp_name+" Attributes");
empInsert.setDefinition(definition);
empInsert.setOwnerName(owner_name_);
emp_id = empDao.insertIntegertype(empInsert);
}catch (Throwable th){
// some code here
}
}
Need to Include the following check:
As mentioned in the code while setting the name of an employee, I am also adding Attributes word in this line empInsert.setName(emp_name+" Attributes");
So, there can be a scenario when the same name is already present in the database and in that scenario, I would like to test
whether that name already exists in the database or not and then only proceed with the insert.
I am wondering is there a way in hibernate which can help me in figuring out this thing?
In case needed, my insertIntegertype hibernate method is defined as follows
public int insertIntegertype(Emp emp)
{
logger.debug("Starting EmpDaoImpl.insert() .....");
Session session = null;
Transaction tx = null;
boolean status = true;
int Emp_id = 0;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
session.persist(emp);
tx.commit();
Emp_id = emp.getEmpId();
} catch(Exception ex) {
tx.rollback();
ex.printStackTrace();
status = false;
} finally {
session.close();
}
logger.debug("Completed EmpDaoImpl.insert() .....");
return Emp_id;
}
Approach :
Make a selection query from database with a like "Name%" if not exist make the Insertion
You have 3 options :
1-Using Native Query
Session session = sessionFactory.openSession();
session.beginTransaction();
String sql = "select First_Name FROM employee where First_Name like 'NAME%'"
NativeQuery query = session.createNativeQuery(sql);
List<Object[]> list = query.list();
if (list.isEmpty()) {
session.persist(emp);
}
2-Using HQL
Session session = sessionFactory.openSession();
session.beginTransaction();
Query query = session.createQuery("select u.name from Employee u where u.name like :Name");
List<Object[]> list= query.setParameter("Name", name+ "%").list();
if (list.isEmpty()) {
session.persist(emp);
}
3-Using CriteriaBuilder
Session session = sessionFactory.openSession();
session.beginTransaction();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<String> criteria = builder.createQuery(String.class);
Root root = criteria.from(class);
Path <String> attribute = root.get(col);
criteria.select(attribute).where(builder.(attribute,NAME + "%"));
List<String> list = session.createQuery(criteria).getResultList();
if (list.isEmpty()) {
session.persist(emp);
}
You should query the database to check if an employee with such name exists. Then you can proceed with saving the employee according to your requirements

Hibernate Session Closed Exception,When 10 or more user access the page

I have a spring MVC application with hibernate.I keep on getting the session closed error, when 10 or more users accessed the same page for reading the data or after fast subsequent requests.
Please help, I needed a crucial fix. It is affecting the customer.
I use the below code
try{
session = sessionFactory.openSession();
tx = session.getTransaction();
session.beginTransaction();
Map<Organization, List<Users>> comToUserLst
= new HashMap<Organization,List<Users>>();
String queryString = "FROM Users as usr Inner Join usr.organization
as org where org.id = :id";
Query query = session.createQuery(queryString);
query.setInteger("id", Integer.valueOf(id));
List<?> comLst = query.list();
Iterator<?> ite = comLst.iterator();
while (ite.hasNext()) {
Object[] objects = (Object[]) ite.next();
Users user = (Users) objects[0];
Organization Organization = (Organization) objects[1];
if (comToUserLst.containsKey(Organization)) {
List<Users> usrLst = new ArrayList<Users>();
usrLst.addAll(comToUserLst.get(Organization));
usrLst.add(user);
comToUserLst.put(Organization, usrLst);
} else {
List<Users> userLst = new ArrayList<Users>();
userLst.add(user);
comToUserLst.put(Organization, userLst);
}
}
} catch (HibernateException e) {
tx.rollback();
e.printStackTrace();
} finally {
tx.commit();
session.close();
}
return comToUserLst;
For update
#Transactional
public Account updateAccount(Account account, UserDetail userInfo) {
session = sessionFactory.getCurrentSession();
Account acct = null;
String queryString = "FROM Account where id = :acctId";
Query query = session.createQuery(queryString);
query.setLong("acctId", account.getId());
acct = (Account) query.uniqueResult();
acct.setName(account.getName());
acct.setPhone(account.getPhone());
acct.setRating(account.getRating());
acct.setFax(account.getFax());
acct.setAccountNumber(account.getAccountNumber());
if (!ValidateUtil.isNullOrEmptyCheckStr(account.getParentAccount()
.getName())) {
acct.setParentAccount(account.getParentAccount());
}
acct.setWebsite(account.getWebsite());
acct.setType(account.getType());
acct.setIndustry(account.getIndustry());
acct.setNumberOfEmployees(account.getNumberOfEmployees());
acct.setDescription(account.getDescription());
acct.setAnnualRevenue(account.getAnnualRevenue());
acct.setEmail(account.getEmail());
acct.setBillingAddress(account.getBillingAddress());
acct.setShippingAddress(account.getShippingAddress());
Users user = new Users();
user.setId(userInfo.getUserId());
// modified details
acct.setModifiedBy(user);
acct.setModifiedDate(new Date());
//update use merge
session.merge(acct);
session.flush();
System.out.println("update Account" + acct.getId());
return acct;
}
Exception
org.hibernate.SessionException: Session is closed!
at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:133)
at org.hibernate.internal.SessionImpl.getTransactionCoordinator(SessionImpl.java:2069)
at org.hibernate.loader.Loader.doQuery(Loader.java:923)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
at org.hibernate.loader.Loader.doList(Loader.java:2553)
at org.hibernate.loader.Loader.doList(Loader.java:2539)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
at org.hibernate.loader.Loader.list(Loader.java:2364)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:496)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:231)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
at com.oi.service.setup.OrganizationService.getOrgToUserLst(OrganizationService.java:311)
at com.oi.service.setup.OrganizationService$$FastClassBySpringCGLIB$$84e99831.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
In Spring it might need to look like this:
#Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Transactional
public Map getOrgToUserLst() {
Map<Organization, List<Users>> comToUserLst = new HashMap<Organization,List<Users>>();
String queryString = "FROM Users as usr Inner Join usr.organization as org where org.id = :id";
List<?> comLst = this.sessionFactory.getCurrentSession()
.createQuery(queryString)
.setParameter(0, Integer.valueOf(id))
.list();
Iterator<?> ite = comLst.iterator();
while (ite.hasNext()) {
Object[] objects = (Object[]) ite.next();
Users user = (Users) objects[0];
Organization Organization = (Organization) objects[1];
if (comToUserLst.containsKey(Organization)) {
List<Users> usrLst = new ArrayList<Users>();
usrLst.addAll(comToUserLst.get(Organization));
usrLst.add(user);
comToUserLst.put(Organization, usrLst);
} else {
List<Users> userLst = new ArrayList<Users>();
userLst.add(user);
comToUserLst.put(Organization, userLst);
}
}
return comToUserLst;
}
#Transactional
public void saveOrganization(Organization org) {
this.sessionFactory.getCurrentSession().persist(org);
}
#Transactional
public void updateOrganization(Organization org) {
this.sessionFactory.getCurrentSession().merge(org);
}
#Transactional
public void deleteOrganization(Organization org) {
getCurrentSession().delete(org);
}
#Transactional
public void deleteOrganizationById(long id) {
final Organization org = this.getCurrentSession().get(Organization, id);
this.getCurrentSession().delete(org);
}
FOR UPDATE
// Get an account object by ID
public Account getAccount(long id) {
session = sessionFactory.getCurrentSession();
String queryString = "FROM Account where id = :acctId";
Query query = session.createQuery(queryString);
query.setLong("acctId", id);
return (Account) query.uniqueResult();
}
// Set account object's attributes
public Account updateAccount(Account acct, UserDetail userInfo) {
acct.setName(account.getName());
acct.setPhone(account.getPhone());
acct.setRating(account.getRating());
acct.setFax(account.getFax());
acct.setAccountNumber(account.getAccountNumber());
if (!ValidateUtil.isNullOrEmptyCheckStr(account.getParentAccount()
.getName())) {
acct.setParentAccount(account.getParentAccount());
}
acct.setWebsite(account.getWebsite());
acct.setType(account.getType());
acct.setIndustry(account.getIndustry());
acct.setNumberOfEmployees(account.getNumberOfEmployees());
acct.setDescription(account.getDescription());
acct.setAnnualRevenue(account.getAnnualRevenue());
acct.setEmail(account.getEmail());
acct.setBillingAddress(account.getBillingAddress());
acct.setShippingAddress(account.getShippingAddress());
Users user = new Users();
user.setId(userInfo.getUserId());
// modified details
account.setModifiedBy(user);
account.setModifiedDate(new Date());
updateAccount(acct);
}
// Update the account object in the database. Here transaction is necessary
#Transactional
private Account updateAccount(Account acct) {
session = sessionFactory.getCurrentSession();
//update use merge
System.out.println("update Account" + acct.getId());
return session.merge(acct);
}
// This is for testing
public void testUpdate(long id, UserDetail userInfo) {
Account acc = getAccount(id);
updateAccount(acct, userInfo);
}
Reference
How are you fetching your sessions SessionFactory.openSession() or SessionFactory.getCurentSession()? Keep in mind that hibernate sessions are not thread safe, hence you require one session per request response cycle.
You should use sessionFactory.getCurrentSession() in place of openSession(). This will maintain the opening and closing sessions automatically.
Also you should use Spring's Transaction using #Transactional with you method. Spring's Transaction management is more efficient than the Hibernate's getCurrentTransaction()

Categories