My web application used hibernate mysql. I can add records to database without having any issue. But if i going to update latest adding record It will not updating. But if I re-start the server(tomcat) and then try to update It's working.
To update the record following condition should be satisfied.
//Check record aready exist
public boolean idExists(String id) {
Session session = (Session) HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<Officer> list = (List<Officer>) session.createQuery("from Officer as p where p.idno =" + "\'" + id.trim() + "\'").list();
return (list.size() > 0) ;
}
Immediate(return 1) adding records It will returns 0. But one restart the server and update the record It will work. I also verify after adding record it's successfully commit to DB.
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static{
try{
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}catch(Throwable ex){
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Let me know if something wrong in my code?
Hibernate does not interact with database immediately after transaction or it does at the time of flushing session, it manages and updates its record to increase system performance in its own way, If you want immediate reflection use :
session.flush();
After updating records.
You could try to flush the session. Entities are not immediately persisted into the database.
session.flush();
I think better you use Transactions here.
You put session.biginTranasaction();
Instead do something like,
public boolean idExists(String id) {
Session session = (Session) HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
List<Officer> list = (List<Officer>) session.createQuery("from Officer as p where p.idno =" + "\'" + id.trim() + "\'").list();
tx.commit();
if(session != null){
session.close();
}
return (list.size() > 0) ;
}
On other end you should generate new session and do other stuffs.
Related
I am using hibernate in my automation testing project, to execute a database 'clean-up routine' that is:
disabling constraints for all tables in the database
removing records by ID's that I stored when creating records used for my automation testing
enabling constraints for all tables in the database
Here is my pseudo code:
private SessionFactory sessionFactory;
private void initialize()
{
try
{
Configuration config = createHibernateConfiguration();
addAnnotatedClassesForClientDB(config);
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
serviceRegistryBuilder.applySettings(config.getProperties());
serviceRegistry = serviceRegistryBuilder.build();
sessionFactory = config.buildSessionFactory(serviceRegistry);
}
catch (HibernateException e)
{
logger.error("Problem creating session factory!");
e.printStackTrace();
}
}
public Session openSession()
{
Session session = sessionFactory.openSession();
session.beginTransaction();
return session;
}
public void cleanClientDatabase()
{
Session session = openSession();
try
{
logger.info("Client DB cleaning started...");
String combinedQuery = // her comes my SQL query
Query query = session.createNativeQuery(combinedQuery);
query.executeUpdate();
closeSession(session);
}
catch (Exception e)
{
logger.error("Failed cleaning Client DB! " + e.getClass().getSimpleName());
e.printStackTrace();
session.getTransaction().rollback();
session.close();
}
}
Now from time to time, it sticks at query.executeUpdate(); in cleanClientDatabase() method and will hang there forever, until I manually kill transaction in Microsoft SQL Management studio by PID.
For some reason an exception is never thrown so I can't tell what is the error, I suspect some sort of lock, what can I do to avoid this issue and fix my code?
Thank you.
I working with PostgreSQL in multithread mode by Hibernate sessions. Init:
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.current_session_context_class">thread</property>
(other strings is connection URL and entity xml describe))
HibernateUtil:
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() {
return sessionFactory.getCurrentSession();
}
public static void close() {
sessionFactory.close();
}
public static void setSessionFactory(SessionFactory factory) {
sessionFactory = factory;
}
}
All CRUD actions with Entities i do in separate class, where every action execute in one transaction.
public class SessionService {
public static <T> T get(Class<T> classvar, int id) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
T result = session.get(classvar, id);
session.getTransaction().commit();
return result;
}
// Some other code
public static void update(Object obj) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.update(obj);
session.getTransaction().commit();
}
}
There is no problems with multithreading work (or i not see it). But, some time ago i seen strange bug. I got one record from db by SessionService.get(Entity.class, 1). Change one field of this entity and save it by SessionService.update(entity). Update was successfull done without exceptions (logging approved). But changes not seen in database. In runtime entity has this changes, but not in db. I wait some time (for flush and others) but nothing changed.
Tried to repeat bug - all good, bug not found. In one day i catch this bug on production server with 19 objects from 200, but in other days i not seen this bug.
Last importan moment: i dont catched this bug with other entities (or i dont see them).
What may be reason of it? May be better use entity manager instead sessions?
Can you please post the entire hibernate.cfg.xml file (delete the username and password of course).
Also are you 100% sure that you do not get an error like (wild guess) :
A different object with the same identifier value was already associated with the session ?
There are errors while running Hibernate, that literary flashes in the console for half a second when running queries.
Had this problem a while back.
on my dao i have two queries. if the first query is successfully committed then second query should run.but if the first query is committed but second query somehow failed to commit/got some exception then the first query which is committed should also be rolled back. how can i do it?
#Repository
public class UpdatePaymentImpl implements UpdatePayment {
#Autowired
SessionFactory sessionFactory;
Session session;
Transaction trans;
#Override
public int updatePayment(#RequestBody UpdateParam updateParam) {
String totalFee=updateParam.getTotalFee();
// float amountPaid=Float.toString(updateParam.getAmountPaid());
String amountPaid=Double.toString(updateParam.getAmountPaid());
//System.out.println(amountPaid);
String depositSlioNo=updateParam.getDepositSlipNo();
String masterId= updateParam.getMasterId();
String advCode=updateParam.getAdvCode();
try{
session=sessionFactory.openSession();
trans=session.beginTransaction();
Query query= session.createQuery
("update CandidateappearagainstadvtcodeEntity cd set cd.paymentstatus='Completed',
cd.amountpaid=:depoFee,cd.challanid=:depositSlip where
cd.studentmasterid=:masterid and cd.advertisementcode=:advCode");
System.out.println(updateParam.getAdvCode());
query.setParameter("depoFee",amountPaid);
query.setParameter("depositSlip",depositSlioNo);
query.setParameter("masterid",masterId);
query.setParameter("advCode",advCode);
int result= query.executeUpdate();
trans.commit();
System.out.println("update successful");
if(result>0){
String masterId1= updateParam.getMasterId();
String advCode1=updateParam.getAdvCode();
Double amountpaid1=updateParam.getAmountPaid();
session = sessionFactory.openSession();
trans = session.beginTransaction();
Query query1 =session.createQuery(" update CandidateappeartoadvtnumberEntity
cnd set cnd.paymentstatus='Completed', cnd.depositedfee=:depofee where
cnd.studentmasterid=:masterid
and cnd.advertisementcode=:advcode");
query1.setParameter("depofee",amountpaid1);
query1.setParameter("masterid",masterId1);
query1.setParameter("advcode",advCode1);
int result1 = query1.executeUpdate();
trans.commit();
System.out.println("updated");
}
return result;
}catch (Exception e){
System.out.println("update error " +e);
trans.rollback();
return 0;
}finally {
session.close();
}
}
}
looks like you creating two different sessions and has separate commit operation.
To reach your goals you have to open one session and one transaction, then execute both queries and only after successful execution do commit.
In that case if any on query execution will fail you won't affect database state. Currently you already commit first query so if your second query will fail the changes from previous query won't be reverted.
Here is an example.
Please Help:
Below error when I tried to add details to tables using hibernate:
NullPointerException
org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.nextTimestamp(RegionFactoryCacheProviderBridge.java:93)
SessionFactoryImpl.openSession(SessionFactoryImpl.java:639)
SessionFactoryImpl.openSession(SessionFactoryImpl.java:648)
com.package1.service.AuthenticateUser.addUser(AuthenticateUser.java:32)
com.package1.controllers.LoginServlet.doPost(LoginServlet.java:68)
AuthenticateUser:
public class AuthenticateUser {
public void addUser(String uname, String uemail, String usrnme,
String upass) {
Session session = factory.openSession(); //Line No:32
Transaction txn = session.beginTransaction();
user.setName(uname);
user.setEmail(uemail);
user.setUsrname(usrnme);
user.setPassword(upass);
txn.commit();
session.save(user);
session.close();
factory.close();
}
private static SessionFactory factory = HibernateSessionManager
.getSessionFactory();
private User user = new User();
}
In LoginServlet I call
authenticateUser.addUser("abcdef", "abcdef","abcdef", "abcdef");
You are closing the factory object, so attempting to open a session with it has chances to cause such a crash (on next call).
Remove this line :
factory.close();
Try to convert this order:
txn.commit();
session.save(user);
Like this:
session.save(user);
txn.commit();
this error ocurrs when you try to create an EntityManager with a closed EntityManagerFactory.
So, the recomandation is,
EntityManagers must be ephimerals *create and close only in the scope of the transaction.
EntityManagerFactory must be application scoped.
NullPointerException
org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.nextTimestamp(RegionFactoryCacheProviderBridge.java:93)
i am using the following approach to sole lazy initialization problem in hibernate.Pleas tell me whether it will work or not .
I have to implement my transcation in my persistance layer compulsary due to some reasons.
public class CourseDAO {
Session session = null;
public CourseDAO()
{
this.session = this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}
public Course findByID(int cid){
Course crc = null;
Transaction tx = null;
try {
tx = session.beginTransaction();
Query q = session.createQuery("from Course as course where course.cid = "+cid+" ");
crc = (Course) q.uniqueResult();
//note that i am not commiting my transcation here.Because If i do that i will not be able to
//do lazy fetch
}
catch (HibernateException e)
{
e.printStackTrace();
tx.rollback();
throw new DataAccessLayerException(e);
}
finally
{
}
return crc;
}
}
and in the filter i am using the folling code
session = HibernateUtil.getSessionFactory().getCurrentSession();
if(session.isOpen())
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
IS this approach right??
Can it can have any problem
could you explain why do you need to have ur transactions in ur repositories? the problem there is that they are going to be so fine-grained, so you are not gonna get any advantage from the session caching
then you are opening the transaction there but closing it in your filter. what happens if you access multiple repositories in your service? Maybe i am not understanding what you mean but i think you need to re-think the reasons that force you to manage your transactions in your repositories
When do you create you CourseDAO? If it is a singleton bean or something else that lives longer than a page view, it will need to keep a SessionFactory and generate a new Session when it needs one rather than keeping a Session.