HibernateTemplate Update Query - java

How to use hql update query using hibernate template
thi is the hql statement "update Login set empSmartId = 48750005" +" where empPassword = 6328ef1675ddb7106eba8dc2661961d7"
using getHibernatetemplate()
Current code:
public class LoginDaoImp extends HibernateDaoSupport implements LoginDao {
public boolean resetAttempt(Login login) {
try { login.setAttempt(0);
getHibernateTemplate().update(login);
return true;
} catch (Exception e) { e.printStackTrace(); }
return false; }
i can save whole pojo class above code work but i want to use where condition to update only hibernateTemplate to update the data

you would be looking something like this
public class LoginDaoImp extends HibernateDaoSupport implements LoginDao
{
public boolean resetAttempt(Login login)
{
try
{
// you should create method for login to retrived based on password
//Remember getting login by password is not correct way, Instead you you should use primary key
//Getting persisted object of Login
Login persisted_login = getLoginByPassword(6328ef1675ddb7106eba8dc2661961d7);
//Setting value in persisted object of Login
persisted_login.setEmpSmartId (48750005);
getHibernateTemplate().update(persisted_login);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

I know this question is very old but, may this solution help someone else...
Here is a trick to update a record in DB.
The trick is first fetch the required record from the DB, update the required fields using setter methods of associated POJO class & then give a call to hibernateTemplate.save(Object entity) method, just like below:-
public void updateUser(User user, String password) {
#SuppressWarnings("unchecked")
List<User> results = (List<User>) hibernateTemplate
.find("FROM User where username = ?", new Object[] { new String(user.getUsername()) });
User userToBeUpdate = results.get(0);
userToBeUpdate.setPassword(password);
hibernateTemplate.save(userToBeUpdate);
}
This is working solution in my case.

Related

Spring Data JPA - how to implement proper exception handling?

I am using Spring Data JPA to process database calls. For this purpose, I have created:
An EmployeeRepository interface, which extends a JpaRepository<Employee, Long>
An EmployeeService, which defines three methods:
Employee saveEmployee(Employee employee);
Optional<Employee> getEmployee(Long id);
Long deleteEmployee(Long id);
An implementation of the EmployeeService:
#Override
public Employee saveEmployee(Employee employee) {
return employeeRepository.save(employee);
}
#Override
public Optional<Employee> getEmployee(Long id) {
return employeeRepository.findEmployeeById(id);
}
#Override
public Long deleteEmployee(Long id) {
employeeRepository.deleteById(id);
return id;
}
The issue is the following:
The get-methods work fine and can return an optional. The save-method, on the other hand, cannot return an optional. Apparently the JpaRepository returns an instance of the saved object upon calling save(). I would rather return an optional, since something could go wrong when saving the employee and in that case, I would like to throw an error - i.e. whenever the optional is not present, I throw an error.
The same holds for the delete-operation: What, for example, if I ask to delete an employee and pass in an id, which does not exist? I would like to catch this error and only then return the passed in id, if the delete operation was successfull. Which error would I have to catch for this purpose? Can someone explain this to me?
=================================================
update:
I have fixed the problem with the delete-call by simply checking if the given employee-id exists before calling `deleteById(id); if it doesn't, the service returns null, if it does, it return the id. The controller looks like this:
#DeleteMapping("/{id}")
public ResponseEntity<Long> deleteEmployee(#PathVariable Long id) {
Long deletedEmployeeId = employeeService.deleteEmployee(id);
if (deletedEmployeeId != null) {
return ResponseEntity.ok(deletedEmployeeId);
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST);
}
I am missing the DataAccessException, however. So, can it be that I would actually have to do the following:
#DeleteMapping("/{id}")
public ResponseEntity<Long> deleteEmployee(#PathVariable Long id) {
try {
Long deletedEmployeeId = employeeService.deleteEmployee(id);
if (deletedEmployeeId != null) {
return ResponseEntity.ok(deletedEmployeeId);
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST);
}
} catch (DataAccessException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
}
This looks a bit like an over-kill to be honest.
I am still a bit unsure how to deal with the save-call. Before I posted this question, my controller was simply doing the following:
#PostMapping
public ResponseEntity<Employee> saveEmployee(#RequestBody Employee employee) {
return ResponseEntity.ok(employeeService.saveEmployee(employee));
}
What happens, if employeeService.saveEmployee(employee) throws a DataAccessException? Am I still returning a HTTP-status-code of 200, as I wrap the response in an ResponseEntity.ok() ?
If so, I would suggest to do the following:
#PostMapping
public ResponseEntity<Employee> saveEmployee(#RequestBody Employee employee) {
try {
Employee savedEmployee = employeeService.saveEmployee(employee);
return ResponseEntity.ok(savedEmployee);
} catch (DataAccessException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Is this something people do? Or are DataAccessExceptions usually neglected as they are not expected?
The method "save" always returns you the same object you are going to save. Only by checking the "id", you can see if the object is saved or not. But if an error occurs in the database, an exception will be thrown and you can catch it by putting "employeeRepository.save(employee)" in a try-catch block. The same way you can do for deleteById

genericdaohibernate add getbyfield other than id

I am using org.appfuse.dao.hibernatepackage and I have used all the method in the GenericDaoHibernate<T,PK> class.
I found these methods
public List<T> getAll();
public List<T> getAllDistinct();
public List<T> search(String searchTerm);
public T get(PK id);
public boolean exists(PK id);
public T save(T object);
public void remove(T object);
public void remove(PK id);
public List<T> findByNamedQuery(String queryName, Map<String, Object> queryParams);
public void reindex();
public void reindexAll(boolean async);
I have some model classes, services and methods.
Now I want to get list of object using some other fieled in the model class other than id(I have some common fields in many model classes).
I need to write similar methods in all the services and daos. So i was thinking is it possible to create a common method in generic dao.
The following I tried, but it didn't work.
public T getbyClientKey(Long clientkey) {
Session sess = getSession();
IdentifierLoadAccess byId = sess.byId(persistentClass);
List<T> entity = (List<T>) byId.load(clientkey);
if (entity == null) {
log.warn("Uh oh, '" + this.persistentClass + "' object with client '" + clientkey + "' not found...");
throw new ObjectRetrievalFailureException(this.persistentClass, clientkey);
}
return entity;
}
I knew this will be error. and it showed TypeCastingException, because return type of byId.load(id) is object only, not List.
So how can I create a method like that?
If so, I think I can create method for remove() also(But that's not necessary for me now, may be in future).
The Javadoc for IdentifierLoadAccess is pretty clear in how the load method should behave:
Return the persistent instance with the given identifier, or null if there is no such persistent instance.
This means it should return just one object, not a List of objects. Try casting it to T instead.
If you want to query your entity (that is, retrieve items by any other means than primary key), you most likely want to implement the search(String) method.
If you want to query your entity (that is, retrieve items by any other means than primary key), take a look at the UserDaoHibernate that is shipped with AppFuse. It contains a method loadUserByUsername() which is implemented like this:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List users = getSession().createCriteria(User.class).add(Restrictions.eq("username", username)).list();
if (users == null || users.isEmpty()) {
throw new UsernameNotFoundException("user '" + username + "' not found...");
} else {
return (UserDetails) users.get(0);
}
}
Obviously, if you want to return all items, it should be modified a bit (this one is made up):
public List<UserDetails> loadLockedUsers() {
List<UserDetails> users = (List<UserDetails>) getSession().createCriteria(User.class).add(Restrictions.eq("account_locked", true)).list();
return users;
}

Hibernate entity lifecycle

I'm getting in trouble trying to separate the business and the persistance in my project.
The skeleton does more or less something like:
private UsuarioBO findById(String idUsuario) {
Usuario dao = getUsuarioDao().findById(idUsuario);
return new UsuarioBO(dao);
}
private void save(UsuarioBO bo){
Usuario dao = bo.bo2dao();
getUsuarioDao().save(dao);
}
Some clarifications about the code above:
UsuarioBO is a business objet and Usuario is an entity mapped to a DB
table.
The new UsuarioBO(dao) is just a mapping method and the
bo.bo2dao() is also a mapping method, but it creates a new empty entity
Usuario.
As you can see, the entity created in both methods is erased of memory on method finish.
The problem goes when i try to do this:
UsuarioBO example = findById("whatever");
save(example);
When i do this, hibernate tells me "there's an existing entity with the same identifier", and thats true! (It's creating an entity on findById() and another on save() ).
The only solution i've found is to use the entity as "bo". I mean, bring the entity object to the service, do whatever modifications on the entity directly, and when i finish do the save sending the entity in spite of a BO.
I'm pretty sure there's a better way of doing so, but how?
EDIT:
this is the save(dao) method:
public void save(Usuario usuario) throws Exception {
try {
getSession().saveOrUpdate(usuario);
} catch (RuntimeException e) {
//error treatment
throw e;
}
}
this is the bo2dao() method (its inside the BO bean):
public Usuario bo2dao() throws Exception {
Usuario dao = new Usuario();
try {
dao.setId(this.id);
dao.setPassword(this.password);
//other similar fields...
dao.setLastLoginTime(this.lastLoginTime);
Role r = new Role();
r.setId(LoginHelper.getRoleId(this.role.getName()));
dao.setRole(r);
Status s = new Status();
s.setId(LoginHelper.getStatusId(this.status.getName()));
dao.setStatus(s);
} catch (Exception e) {
throw e;
}
return dao;
}
In this case, Role and Status are also entity beans connected with Usuario (one user can only have one role and one status).
getRoleId() and getStatusId() returns the correspondent id from the name (for example: "UNLOCKED" returns 1)

Java Class's property not getting set when passing through parameter

I have two classes
here's code
public class LoginServiceImplementation implements LoginService {
public boolean validateLogin(Login login)
{
LoginDao loginDao=DaoFactory.getLoginDao();
boolean b=loginDao.validateLogin(login);
System.out.println("id=="+login.getLoginId()+" uname=="+login.getuName()+" pass== "+login.getPassword());// values reset to null
return b;
}
}
public class LoginDaoImplementation implements LoginDao {
#Override
public Login validateLogin(Login login) {
Session session= Hibernate.getHibernateSession();
Query query= session.createQuery("from Login where uName= 'user' and password= 123");
//query.setParameter("uname", login.getuName());
//query.setParameter("pwd", login.getPassword());
//System.out.print(login.getuName());
//System.out.print(login.getPassword());
try
{
List<Login> logins=query.list();
System.out.print(logins.size());
if(logins.size()>0)
{
Login l=new Login();
l=logins.get(0);
login=l;
System.out.println("id=="+login.getLoginId()+" uname=="+login.getuName()+" pass== "+login.getPassword());/// ALL values getting printed
return login;
}
session.close();
return null;
}
catch(HibernateException x)
{
x.printStackTrace();
session.close();
return null;
}
}
}
when calling validatemethod of DaoImplementation class from serviceImplementation class, DaoImplementation class sets the values in the login object which is passed as parameter, but in serviceimplementation class i'm getting same old object with all values set to null.
Please reply with reason and solution.
thank you
login=l;
That does not work. You are just assigning a new object to the local variable login. This has no effect on the object that was previously stored in that variable (and that is visible to the outside world). Java does not support pass-by-reference, so you cannot re-assign variables outside of your scope.
You need to either copy all the data into that object (using setters), or (my preference) return a Login object from the method that the caller can use. (It is not clear if you are already doing that, part of the sample seems to return boolean, part seems to return a Login object).

Using Spring HibernateTemplate. How to delete by Id?

For work with database, my class extends HibernateDaoSupport class and inside the methods I'm using Spring HibernateTemplate.
So, for delete a row in database I use this method:
public void delete(MyObject obj) {
getHibernateTemplate().delete(obj);
}
all ok!
But, at this moment I'm trying to implement a method that can delete a row based on id:
public void delete(final long id) {
// some code here
}
And I can't find some HibernateTemplate method like this:
getHibernateTemplate().remove(id)
What is a good solution for me in this case?
delete using particular id,
public void delete(long id)
{
Session session ;
MyObject myObject ;
session = sessionFactory.getCurrentSession();
myObject = (MyObject)session.load(MyObject.class,id);
session.delete(myObject);
//This makes the pending delete to be done
session.flush() ;
}
Also consider encapuslate this methods in try/catch/finally and log the error as needed
Another alternative is:
public void deleteById(Class clazz,Integer id) {
String hql = "delete " + clazz.getName() + " where id = :id";
Query q = session.createQuery(hql).setParameter("id", id);
q.executeUpdate();
}
As you mentioned, there s not such method in HibernateTemplate. You can do the following,
hibernateTemplate.delete(hibernateTemplate.get(Class,Id));
You can also use below method:
public void deleteById(Class clazz,Integer id) {
hibernateTemplate.bulkUpdate("delete from "+clazz.getName()+" where id="+id);
}
There is a simple solution by creating an object and setting only the ID:
Product product = new Product();
product.setId(37);
session.delete(product);
The drawback of this simple solution is that it doesn’t remove the associated instances.
If you have some attribute (another entity related) of the product to be deleted, you will need to load the product before.
Serializable id = new Long(17);
Object persistentInstance = session.load(Product.class, id);
if (persistentInstance != null)
{
session.delete(persistentInstance);
}
This will issue (if you have an attribute table in cascade) a delete on the children attributes.

Categories