What I am missing here (Hibernate begin transaction) - java

I have a test class :
class SomeTest {
public static void main(String args[]){
Client kom = new Client();
kom.setId(kom.newID());
kom.setClient("OldName");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(kom); // I think insert is here ?
Query q = session.createSQLQuery(" call change_name(:old, :new) ");
q.setParameter("old","OldName");
q.setParameter("new","NewName");
int result = q.executeUpdate();
session.getTransaction().commit();
}
};
And database stored procedure change_name which do update of name of client.. every time I run test I have one record with old name ?? I expect that update is execute in same transaction and that I never see old name ?

JB Nizet has right answer..
save() does NOT insert. It associates the object with the session. The insert query is executed at the next flush. So call flush explicitely before calling your stored proc. – JB Nizet yesterday
There is also FlushMode ... I set to ALWAYS. I call many procedures which change data in database..

Related

procedure call not working from java call

I have created a procedure which updates a table row in DB and returns a specific string(e.g 'done') after the update it returns a different response if the value is not updated(e.g 'fail').
When calling from MySQL tool it's updating the table and returning the value in response
call LoginCheck('9111111114','AGGR001002','11d3ad9315b7be5dd53b31a273b3b3aba5defe700808305aa16a3062b76658a791','DIST001007');
However when I am calling the same procedure from Java code it's returning the proper response i.e 'done', but when I am checking the table it seems that it has not updated the respective table row.
factory = DBUtil.getSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
String status = "7000";
List objectList = null;
SQLQuery query = session.createSQLQuery("call LoginCheck(:userid,:AggId,:Password,:id)");
query.setString("userid", userid);
query.setString("AggId", AggId);
query.setString("Password", Password);
query.setString("id", id);
objectList = query.list();
I have already tried query.setParameter and query.ExecuteUpdate()
Please let me know if anything else is required from my side.
It seems that you have begin your transaction but not committed it . so try commit it .
Transaction transaction = session.beginTransaction();
transaction.commit()

Hibernate doesn´t work as expected

I am trying to update MySQL table with hibernate. It looks like that it does work, result from hibernate is 1, but table doesn´t change. My code for update :
Session session = GeneralSession.getSession();
session.beginTransaction();
//some code - initialization and logics
//loop
Query updateDuplicity = session .createSQLQuery("UPDATE `t_inzerat` set `actual` = 'D'
WHERE `id` = "+ idSimi);
int resultUpdate = updateDuplicity.executeUpdate();
session.flush();
//end of loop
session.getTransaction().commit();
In console hibernate writes this as:
Hibernate: UPDATE `t_inzerat` set `actual` = 'D' WHERE `id` = 5611
Affected rows : 1
Please what is wrong? Thank you
Have a look hereexample. Do the commit in the tx returned by beginTransaction method

Hibernate retrieve query not working

I have a hibernate implementation inside my JSF2 code trying to list some records from MySQL DB. There are following code snippets: Search.java - implementing the querying logic; Student.java - implementing the record saving logic.
The problem I am facing is whenever I run Search.java, the result returned is 'null'.
Please note - my DB has already many entries and even when I tried to query Student myStudent = session.get(Student.class, 23); it returned me 'null'.
Here 23 is the id field in the SQL table. Also, the table has auto-generated PK as id. I have another class for inserting the records that works perfectly fine.
Search.java:
public class Search {
public static void main(String[] args) {
// create session factory
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(Student.class).buildSessionFactory();
// create session
Session session = factory.getCurrentSession();
try {
// start a transaction
Student tempStudent = new Student("bob", "thebuilder", "good", "blabla#bla.com", "(456)-456 5897");
session.beginTransaction();
session.save(tempStudent);
// commit transaction
session.getTransaction().commit();
System.out.println("id of the student is " + tempStudent.getId());
session = factory.getCurrentSession();
session.beginTransaction();
System.out.println("student with id " + tempStudent.getId());
Student myStudent = session.get(Student.class, tempStudent.getId());
session.getTransaction().commit();
System.out.println("Done!");
} finally {
factory.close();
}
}
}
Please advise what mistake I might have made here. I've spent hours googling. Also, please forgive me for my (possibly) rookie mistakes, I am new to Hibernate and to this website.
Let me know if I need to post error stack or my cfg.xml as well.
As I can see in your case id of tempStudent is 0. You need to get from session by id of saved student.
Try this:
Serializable id= session.save(tempStudent);
...
Student myStudent = session.get(Student.class, id);
Also you can enable show_sql property in your hibernate.cfg file. It will log all generated sql, so you can chek if it is ok.

hibernate sets dirty flag (and issues update) even though client did not change value

hibernate dirty flag works great for what they call "persistent" objects https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html
but i have a web app, where the hib mang entity Order is also used as the Spring MVC command object. so when my controller marshals the request into an order, it is what hibernate calls a "detached" object. my problem senario can be illustrated with 2 web clients and 4 web requests against a single order.
1 - client 1 opens the order in detail view
2 - client 2 opens the same order and updates attribute 1
3 - client 1 clicks "save" to update any changed fields, but actually has not updated anything
in step 3, client 1 issues session.update(order) (also tried session.merge() and session.saveOrUpdate()) and ends up reverting attribute 1 back to its original value. if it was a "persistent" object, then hibernate would have known that nothing had changed. but because it is a detached object, hibernate actually issues an update for every member of the Order object.
Any ideas on how to get the dirty flag in hibernate detached objects to work like it does in persistent objects?
test
first test shows hibernate working with persistent objects, works great, session 1 issues no updates:
try{Class.forName("net.sourceforge.jtds.jdbc.Driver");} catch(Exception e){e.printStackTrace();}
Session session1 = null;
Session session2 = null;
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session1 = sessionFactory.openSession();
session2 = sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();
// order 1 has a null dig user
//session 1 opens order 1
//session 2 opens order 1
//session 2 assigns andrew as dig, save
//session 1 hits save
Query qo1 = session1.createQuery("select o from Order o where o.id = 536258");
Order o1 = (Order)qo1.list().get(0);
Query qo2 = session2.createQuery("select o from Order o where o.id = 536258");
Order o2 = (Order)qo2.list().get(0);
Query qu2 = session2.createQuery("select u from User u where u.id = 7");
User u2 = (User)qu2.list().get(0);
System.out.println("update user session 2 begin");
o2.setDigitizer(u2);
System.out.println("update user session 2 end");
System.out.println("session 2 save begin");
session2.save(o2);
session2.flush();
tx2.commit();
session2.close();
System.out.println("session 2 save end");
System.out.println("session 1 save begin");
session1.save(o1);
session1.flush();
tx1.commit();
session1.close();
System.out.println("session 1 save end");
then here is the same idea but with detached objects and client 1 ends up reverting the update made by client 2:
try{Class.forName("net.sourceforge.jtds.jdbc.Driver");} catch(Exception e){e.printStackTrace();}
Session session1 = null;
Session session2 = null;
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
System.out.println("session 1a start");
session1 = sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Query qo1 = session1.createQuery("select o from Order o where o.id = 536258");
Order o1 = (Order)qo1.list().get(0);
session1.flush();
tx1.commit();
session1.close();
System.out.println("session 1a end");
System.out.println("session 2 start");
session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
Query qo2 = session2.createQuery("select o from Order o where o.id = 536258");
Order o2 = (Order)qo2.list().get(0);
Query qu2 = session2.createQuery("select u from User u where u.id = 7");
User u2 = (User)qu2.list().get(0);
o2.setDigitizer(u2); //here is session 2 update to the order
session2.flush();
tx2.commit();
session2.close();
System.out.println("session 2 end");
//here is the "detached" part, new session, but same domain object instance from above
System.out.println("session 1b start");
session1 = sessionFactory.openSession();
tx1 = session1.beginTransaction();
session1.update(o1); //tried merge -- same result, we revert the session 2 update
session1.flush();
tx1.commit();
session1.close();
System.out.println("session 1b end");
You don't need to call save if the entity is detached. That is meant only for persisting a transient entity.
In your case you need to merge the detached entity and make sure you use optimistic locking too, because you use two different Sessions (one for loading and the second for updating) and meanwhile the actual database object might have changed by some other concurrent request.
If you use property-level access, then you need to make sure you don't mess with the actual Hibernate collections, like when wrapping them into some other collection object. In that case, Hibernate will detect those collections as dirty, even if the actual content hasn't changed.
you're pretty much stuck using an interceptor for this. hibernate is VERY AGGRESSIVE about detecting deltas on an object, to the point of not caring if the value actually deltas, only that the mutator methods are called.
it is annoying but the overhead of recursive descent and the possibility of circularity preclude a more definitive dirty detection on an abstract level.

How to retrieve database table value in hibernate?

I am new to the Hibernate, i want to retrieve table values from database, I have a code but it returns object values. My sample code is,
Configuration conf=new Configuration();
#SuppressWarnings("deprecation")
SessionFactory sessionfactory=conf.configure().buildSessionFactory();
Session session=sessionfactory.openSession();
List maintable = null;
try
{
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery ("select main.empid,main.address from Main as main");
maintable =q.list();
Object[] obj=maintable.toArray();
for(int i=0;i<obj.length;i++)
{
System.out.println("column valuse : "+obj[i]);
}
tx.commit();
session.close();
}
catch(Exception e1)
{
System.out.println("Exception");
}
I need to get multiple column values...How can i do that?
I can retrieve value from list easily.But in my above question i print only object property not a value.
Query qry=session.createQuery("from Main");
List<Main> user=(List<Main>) qry.list();
session.getTransaction().commit();
session.close();
for(Main u : user)
{
System.out.println("User id : "+u.getEmpid());
System.out.println("User Address:"+u.getAddress());
}
This is what Hibernate (or JPA rather) is meant for. If you want to access regular values, use JDBC instead.
It’s very useful when we retrieve some fields/properties from our entity class. The above query with “new” keyword can return a list of type “Main”. If we do not use such a keyword and specify the fields directly, a list of type Object [ ] is retrieved.
select new Main(main.empid,main.address) from Main as main ,
select main.empid,main.address from Main as main
please check that empid,address are the column name in the database or the property name of Main class.
It should be the property name of entity(i.e Main) class.

Categories