Hibernate execute update with criteria - java

Is it possible to execute an update while using Criteria in Hibernate? For example:
Session session = getSession();
Criteria crit = session.createCriteria(User.class);
crit.add(Restrictions.eq("token", sessionToken));
User user= new User();
Transaction tx = session.getTransaction();
try
{
tx.begin();
session.updateWithCriteria(user, crit); //my imaginary function
tx.commit();
}
catch (Exception e)
{
e.printStackTrace();
tx.rollback();
}
session.close();

There is a very powerful feature called:
15.4. DML-style operations
small cite from doc:
... However, Hibernate provides methods for bulk SQL-style DML statement execution that is performed through the Hibernate Query Language...
So, while this is not about criteria - we still can use our domain model for querying, because it is about HQL. This is a snippet showing the power:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
SUMMARY: Having that in place:
we can use query to filter results
we can apply bulk update on it
we won't need to load these rows in memory, into the session...

Now we can do something like this for bulk update and delete. New api's released for criteriaUpdate and CriteriaDelete
CriteriaBuilder cb = this.em.getCriteriaBuilder();
// create update
CriteriaUpdate<Order> update = cb.createCriteriaUpdate(Order.class);
// set the root class
Root e = update.from(Order.class);
// set update and where clause
update.set("amount", newAmount);
update.where(cb.greaterThanOrEqualTo(e.get("amount"), oldAmount));
// perform update
this.em.createQuery(update).executeUpdate();

First you should get the object then modify and update:
Query q = session.createQuery("from StockTransaction where tranId = :tranId ");
q.setParameter("tranId", 11);
StockTransaction stockTran = (StockTransaction)q.list().get(0);
stockTran.setVolume(4000000L);
session.update(stockTran);
If you want to use partial/dynamic update feature then put
#org.hibernate.annotations.Entity(
dynamicUpdate = true
)
annotation on top of the dao class.
Example from: http://www.mkyong.com/hibernate/hibernate-dynamic-update-attribute-example/
Note: The Question is "with criteria" but the accepted answer is NOT "with criteria" but SQL.

Related

Get entity by email in hibernate

I am trying to get the user from his email , the email is unique in the database.
I write this code :
session.beginTransaction();
User user = (User) session.createQuery("select * from `user` where email = '"+email+"'");
session.getTransaction().commit();
Is this code right ? or there is some function in hibernate to get entity by column value ?
I see two problems with your current code. First, you appear to be running a native SQL query, not HQL (or JPQL). Second, your query is built using string concatenation, leaving it prone to attack by SQL injection
Consider the following code:
Query query = session.createQuery("from User u where u.email = :email ");
query.setParameter("email", email);
List list = query.list();
Without writting any SQL:
public static Person getPersonByEmail(String email) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Person> cr = cb.createQuery(Person.class);
Root<Person> root = cr.from(Person.class);
cr.select(root).where(cb.equal(root.get("email"), email)); //here you pass a class field, not a table column (in this example they are called the same)
Query<Person> query = session.createQuery(cr);
query.setMaxResults(1);
List<Person> result = query.getResultList();
session.close();
return result.get(0);
}
example of use:
public static void main(String[] args) {
Person person = getPersonByEmail("test#mail.com");
System.out.println(person.getEmail()); //test#mail.com
}

Delete all objects from database in hibernate Spring java

I want to delete all those rows from xyz table where id = 1 using hibernate spring.
I have tried following code but its not giving error but not deleting rows -
Session session = (Session) getEm().getDelegate();
String sql ="Delete from xyz where id=:id" ;
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("id", "1");
int flg = query.executeUpdate();
Can you please help me to delete all rows using hibernate query.
Try wrapping your code within a transaction like this:
Session session = (Session) getEm().getDelegate();
Transaction tx = session.beginTransaction();
String sql ="Delete from xyz where id=:id" ;
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("id", "1");
int flg = query.executeUpdate();
tx.commit();
Try
query.setParameter("id", Long.valueOf(1));
if your entity is of type Long (which ideally should be).
Reference: http://www.codejava.net/frameworks/hibernate/hibernate-basics-3-ways-to-delete-an-entity-from-the-datastore
Note: The link is just for your reference.
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();
}

How can I add a value to a column?

I want to add a value to an existing column, but I don't want to have to select it first. Right now I would have to do something like
// run hql in a named query
from Employee where id = :id
// after running the above
e.setBonus(e.getBonus() + 100); // add 100 to e's bonus
// commit to database
HibernateUtil.saveOrUpdate(e);
But I want something that's just one-and-done - something like
update Employee e set e.bonus = e.bonus + 100
Is this something I can do in Hibernate? If so, how. If not, what's the suggested best practice for such an update?
You could create a hql query that just does an update
Query updateBonus = createQuery("UPDATE Employee SET bonus = bonus+100 WHERE id = :id" );
updateBonus.setInteger("id", employee.getId());
updateBonus.executeUpdate();
Yes, you can do it as intended with hql query. Try such code:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hql="update Employee e set e.bonus = e.bonus + :p where id=:id";
session.createQuery(hql).setInteger("p",100).setInteger("id",id).executeUpdate();
tx.commit();
session.close();
More info you can find by the link

How to join tables using hibernate criteria

I am trying to join multiple table to join using criteria but getting error in doing so can someone please help me in it
My code is
final Session session = getSession();
final Criteria criteria = session.createCriteria(ReferralPaymentInfo.class).createCriteria("SIGNUP_REFERRAL");
System.out.println("before");
List list = criteria.list();
System.out.println("after");
I also tried this code
final Session session = getSession();
final Criteria criteria =session.createCriteria(ReferralPaymentInfo.class);
criteria.setFetchMode("SIGNUP_REFERRAL", FetchMode.JOIN);
List list = criteria.list();
This gives result only from table ReferralPaymentInfo and not considering table SIGNUP_REFERRAL
Can some one please help me out
T
try this
DetachedCriteria ownerCriteria = DetachedCriteria.forClass(Owner.class);
ownerCriteria.setProjection(Property.forName("id"));
ownerCriteria.add(Restrictions.eq("ownername", "name"));
Criteria criteria = getSession().createCriteria(Pet.class);
criteria.add(Property.forName("ownerId").in(ownerCriteria));

problem with HQL update

When I try to execute the following HQL query:
Query query = getSession().createQuery("update XYZ set status = 10");
query.executeUpdate();
I get this exception:
Exception in thread "main" org.hibernate.QueryException: query must begin with SELECT or FROM: update
EDIT:
I also tried following .But it doennot work either.
org.hibernate.Query query = getSession().createQuery("update XYZ t set t.status = 10");
EDIT2:
Making changes in hinbernate.cfg.xml solved my problem
Earlier i was using
setting hibernate.query.factory_class" = org.hibernate.hql.classic.ClassicQueryTranslatorFactor
Now am using following property
<property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
Thats not an HQL query.
You want to import javax.persistence.Query which allows normal sql,
not org.hibernate.Query which works on entity objects.
If you want to use simple sql, you could also use PreparedStatement
However, if you really want to use hibernate, without taking advantage of entityobjects (totally defeating the point of using hibernate in the first place, imho) you could do it like this (reference docs):
String myUpdate = "update XYZ myAlias set myAlias.status = :newStatus";
// or String noAliasMyUpdate = "update XYZ set status = :newStatus";
int updatedEntities = getSession().createQuery(myUpdate) //or noAliasMyUpdate
.setInt( "newStatus", 10 )
.executeUpdate();
The question is thinking in SQL, when you should be thinking in objects:
XYZ xyz = new XYZ();
xyz.setStatus(10);
getSession().merge(xyz);
Try:
Query query = getSession().createQuery("update XYZ o set o.status = 10");
query.executeUpdate();
Take a look at this also.
Session sesssion = getSession(); //getter for session
For HQL :
String hql = "update Activity " +
"set startedOn = :taskStartedOn " +
"where id = :taskId";
Query query = session.createQuery(hql);
query.setDate("taskStartedOn",new Date());
query.setLong("taskId",1)
int rowCount = query.executeUpdate();
Here Activity is POJO.
Use
hibernate.query.factory_class = org.hibernate.hql.ast.ASTQueryTranslatorFactory
in hibernate.cfg.xml file to resolve exception:
org.hibernate.QueryException: query must begin with SELECT or FROM: update.....

Categories