Currently, I am having this code to insert a Product object and it works totally fine!
public void insertProduct(Product product) {
Session session = this.databaseDriver.openSession();
Transaction transaction = session.beginTransaction();
session.save(product);
transaction.commit();
session.close();
}
However, this code does not seem to work:
public void insertProduct(Product product) {
Session session = this.databaseDriver.openSession();
session.save(product);
session.flush();
session.close();
}
What would be the reason for this? Neither does it give me any errors nor insert the data.
In hibernate even after calling session.flush it only updates an existing instance of the object not add a new one .Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.
Related
I am new to hibernate. I want to understand behavior once the transaction is commit. Consider below code-
Employee class is the class whose objects will be inserted/deleted to/from the database.
public static void main(String[] args) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
long id = 2;
try {
session.beginTransaction();
Employee employee = (Employee) session.get(Employee.class, id);
session.delete(employee);
session.getTransaction().commit();
employee.getName(); /*What will happen at this line*/
}
catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
It becomes "Transient". From the Session class documentation
Persistent instances may be made transient by calling delete()
From the guide:
Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition).
Take a look here for more info https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html
I have an application which works on Spring MVC and Hibernate . It works fine if a single user insert a record, but if multiple user insert records concurrently at same time . It shows this error "Hibernate: org.hibernate.AssertionFailure: null id in".I can observe this is happening because the automatic primary id genaration by hibernate for all record can be similar because of same time. not sure about this.Please help. Need a crucial fix.
The code I use as follow
#Transactional
public Account addAccount(Account acct) {
session = sessionFactory.getCurrentSession();
session.save(acct);
session.flush();
session.clear();
return acct;
}
If you are having concurrency problems consider create this class:
public AccountConcurrencyUtils {
public static synchronized Account addAccount(Account acct, SessionType session) {
session = sessionFactory.getCurrentSession();
session.save(acct);
session.flush();
session.clear();
return acct;
}
}
Finally in your code:
#Transactional
public Account addAccount(Account acct) {
return AccountConcurrencyUtils.addAccount(acct, session);
}
This should provent concurrency problems, there should be betters workarounds if you are using Java 7 but this should
fix your problem if it is about concurrency, if not, the problem may be other.
I updated the code, put the Session type you are using, this should work even for older Java versions like java 5
As i know Hibernate keep track persistent object till session.close().
after session.close() the persistent object become detached object and hibernate doesn't know about this object.
i have some confusion in below two code sample.
in first code sample :- open only one session and persist a object after session.close() this object become detached and we can't perform update (e.g object.setName() ).
but in second code sample we make object detached and perform setter on object and again open a session and update this detached object. but how this second session know the above setter value or update..
package objectState;
import org.hibernate.Session;
import org.hibernate.Transaction;
import HibernateUtils.HibernateUtils;
public class ObjectStateTest {
public static void main(String[] args)
{
UserDetails user = new UserDetails(); // Transient Object
user.setUserName("Test User");
Session session = HibernateUtils.getFactory().openSession();
Transaction tx = session.beginTransaction();
session.save(user); //Persistent Object
user.setUserName("updated user"); //HB Keep Track Persistent Object & Perform Update if any change
tx.commit();
session.close();
user.setUserName("update after session closed"); // Detached Object (HB keep track Object until session.close() )
}
}
DetachedToPersistent.java
package objectState;
import org.hibernate.Session;
import org.hibernate.Transaction;
import HibernateUtils.HibernateUtils;
public class DetachedToPersistent {
public static void main(String[] args) {
UserDetails user = new UserDetails(); //Transient Object
user.setUserName("Test User");
Session session = HibernateUtils.getFactory().openSession();
Transaction tx = session.beginTransaction();
session.save(user); //Persistent Object
tx.commit();
session.close();
user.setUserName("update Detached User"); //Detached Object
session = HibernateUtils.getFactory().openSession();
tx = session.beginTransaction();
session.update(user); // Persistent Detached Object
tx.commit();
session.close();
}
}
may be i made some mistake to understand please point out my mistake..
Thankx :)
First, I recommend you reading a bit about entity state transitions.
When an object is attached, the Persistence Context detects changes using the automatic dirty checking mechanism.
When the object becomes detached (because the Session that loaded it has closed) you can either:
merge the entity by calling session.merge(entity), that fetches a new fresh copy and updates it with the merging entity.
attach the entity by calling the legacy session.update(entity)
The merge method is preferred to update, so use merge whenever possible.
I have been making a simple program to save an employee details in mysql using hibernate framework as follows...
public class Manifest {
Session session;
public static void main(String[] args) {
Employee employee = new Employee("varun");
new Manifest().addEmployee(employee);
}
/* Method to CREATE an employee in the database */
public void addEmployee(Employee employee){
Integer employeeID=null;
SessionGenerator sessionGenerator = new SessionGenerator();
try{
session = sessionGenerator.getSessionToDb();
employeeID = (Integer) session.save(employee);
System.out.println(employeeId);
}catch (HibernateException e) {
e.printStackTrace();
}finally {
session.close();
}
}
}
I am aware of the fact that I should use session.beginTransaction(); & tx.commit() but my question is that why no exception is thrown here in my case and it is printing employeeId on console but not making any entry in database.. What the reason behind that???
1) Session.save() may perform an INSERT outside transaction boundaries: save() method returns an identifier, and if an INSERT has to be executed to get the identifier (e.g. "identity" generator), this INSERT happens immediately (in order to get an identity), no matter if you are inside or outside of a transaction.
2) Commit might happen even without transaction if you set:
<property name="connection.autocommit">true</property>
that's why an exception is not raised
Check this article (Working nontransactionally with Hibernate): https://developer.jboss.org/wiki/Non-transactionalDataAccessAndTheAuto-commitMode
I have little problem. When I try insert new value to database, function save() inserts me different values than are at object :(. What should I do?
Here is my function
public void updateListOfElements(List<Dokumenty> list) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
for (Dokumenty dokument : list) {
Dokumenty dokumentToUpdate =
(Dokumenty) session.get(Dokumenty.class, dokument.getId());
dokumentToUpdate.setAktywny('N');
session.update(dokumentToUpdate);
// id z dupy wpisuje
dokument.setId(10114);
session.save(dokument);
}
transaction.commit();
} catch (HibernateException e) {
if (transaction != null) {
transaction.rollback();
}
} finally {
session.close();
}
}
You should use saveOrUpdate not save
dokument.setId(10114);
session.saveOrUpdate(dokument);
When you call saveOrUpdate() If the identifier exists, it will call update method else the save method will be called.
If you call save() method stores an object into the database. That means it insert an entry.
Before proceed have a look :What are the differences between the different saving methods in Hibernate?
My suggetion:Always use saveOrUpdate //if record exists update otherwise new
Use session.merge(). Becuase, NonUniqueObjectException may be thrown when using Session.saveOrUpdate() in Hibernate - See more at: http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/#sthash.WJEbdSaG.dpuf