While developing a web application using spring and hibernate i am getting the following execption.
java.sql.SQLException: ORA-02289: sequence does not exist
While i am trying to insert the data into a table i am usign sequence to increment the value of request_id.
I am using the following coding for inserting
#Override
public void postRequest(RequestInfo requestInfo)
{
Session session = null;
Transaction trans = null;
SessionFactory sessionFactory = null;
sessionFactory=HibernateConfig.getSessionFactory();
session= sessionFactory.openSession();
trans = session.beginTransaction();
session.save(requestInfo);
trans.commit();
session.close();
}
public class HibernateConfig
{
public static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory()
{
sessionFactory = new Configuration().configure().buildSessionFactory();
return sessionFactory;
}
}
In hibernate mapping i have mentioned like this
<id name="requestId" type="int" column="request_id" >
<generator class="sequence">
<param name="sequence">REQUEST_INFO_SEQ</param>
</generator>
</id>
I tried with native also but i couldn't get the values to be get inserted.
i am using oracle 11g.
Can any one give me solution for this.
The insert operation is working fine after giving the sequence name with the schema name like schemaName.sequenceName in the hbm.xml file.
Thank you all for responding the query.
Does the sequence exist? To check, do:
select * from all_sequences where sequence_name = 'REQUEST_INFO_SEQ'
i think there is something wrong with the POJO object comming in parameter, you should create session first the do 3 things , making POJO object (transient state) then calling persistent methods save,update,delete(Persistent State) and trx.commit(Detached state of hibernate object). and should do this work in try catch block and catch HibernateException and then call finally which will close the session, and use buildSessionFactory();
sessionFactory = new Configuration().configure().buildSessionFactory();
Related
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.
When using hibernate, I would like to see if SessionFactory and Session objects can work with "try-with-resource", so that I can't ignore invoking their close() methods:
try (SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession()){
session.beginTransaction();
Customer customer = new Customer();
customer.setFirstName("James");
customer.setLastName("Bond");
customer.setSsn(999998);
customer.setAddressLine1("1111 S St");
customer.setCity("London");
customer.setState("LDN");
customer.setCountry("UK");
session.save(customer);
session.getTransaction().commit();
// session.close();
// sessionFactory.close();
} catch (Exception e) {
e.printStackTrace();
}
I get the errors however:
CustomerTest.java:12: error: incompatible types: try-with-resources not applicable to variable type
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
^
(SessionFactory cannot be converted to AutoCloseable)
CustomerTest.java:18: error: incompatible types: try-with-resources not applicable to variable type
Session session = sessionFactory.openSession()){
^
(Session cannot be converted to AutoCloseable)
2 errors
Does it mean that SessionFactory and Session objects can't work with "try-with-resource", because the two classes don't implement AutoCloseable interface?
Thanks.
Does it mean that SessionFactory and Session objects can't work with
"try-with-resource", because the two classes don't implement
AutoCloseable interface?
Yes, that's exactly what it means.
If you take a look at newer versions of Hibernate, however, you'll find that both SessionFactory and Session do implement the AutoCloseable interface there.
I think the change was made in Hibernate 5, so upgrading your version of Hibernate could be a potential solution.
This has been fixed in hibernate version 5. If you can upgrade to version 5, please use this. Supported Jira ticket
https://hibernate.atlassian.net/browse/HHH-8898
For project which cannot upgrade, for that we can implement our own CloseableSession interface.
public class CloseableSession implements AutoCloseable {
private final Session session;
public CloseableSession(Session session) {
this.session = session;
}
public Session getSession() {
return session;
}
#Override
public void close() {
session.close();
}
}
Usage
try (CloseableSession session = new CloseableSession(
sessionFactory.openSession())) {
}
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 have buit a Webservice using these technologies + c3p0 for database handling. It works ok most of the time but I have a 3-5% ratio (sometimes even a 10%) of failed acces due to this error.
I am using Hibernate this way:
-Session Factory
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
// Create the SessionFactory from hibernate.cfg.xml
return configuration
.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
//reabrimos la sesion si esta cerrada al liberar los recursos
if(sessionFactory.isClosed())
{
System.out.println("Reopen session");
sessionFactory.openSession();
}
return sessionFactory;
}
Then in my hibernate.cfg.xml I have the following line:
<property name="current_session_context_class">thread</property>
Finally in my endpoints I have defined a hibernate_session class which I use as follows:
#Path("/projects")
public class ProjectServiceImpl {
#Context
SecurityContext security;
Session hibernate_session = null;
#POST
#Path("sync.json")
#Produces(value = {"application/json",
"application/vnd.myapp-v1+json",
"application/vnd.myapp-v2+json"})
public Response syncProjects(
#DefaultValue("") #FormParam("projects") String in_projects_str,
#DefaultValue("0") #FormParam("last_sync") long last_sync,
#Context Request request) {
//...
hibernate_session = HibernateUtil.getSessionFactory()
.getCurrentSession();
if (hibernate_session == null) {
ResponseMessage rm = new ResponseMessage();
rm.setCode(Status.INTERNAL_SERVER_ERROR.getStatusCode());
rm.setMessage("Hibernate Session is Null");
rm.setType("ERROR");
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(rm)
.type("application/json").build();
}
try {
hibernate_session.beginTransaction();
//Database work...
hibernate_session.flush();
hibernate_session.getTransaction().commit();
}catch (RuntimeException | IllegalAccessException
| InvocationTargetException e) {
try {
if (hibernate_session.getTransaction() != null) {
hibernate_session.getTransaction().rollback();
}
} catch (RuntimeException rbe) {
System.err.println("Couldn’t roll back transaction");
}
e.printStackTrace();
ResponseMessage rm = new ResponseMessage();
rm.setCode(Status.INTERNAL_SERVER_ERROR.getStatusCode());
rm.setMessage(e.getMessage());
rm.setType("ERROR");
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(rm)
.type("application/json").build();
}
}
return Response.ok().entity(result_entity)
.type("application/json").build();
}
My hibernate_session is a class attribute, do I have to change it to a local variable?. As far as I know the end points will be executed in different threads so I have assumed that I am working with different instances of my endpoint container class and these class attributes will not get overriden by multiple request.
Any light you can shed on this topic will be appreciated,
Thanks in advance
Thanks all for your replies. I finally managed to solve the problem.
In one of my multiple entries there was a begin transaction (necessary to create criterias) but was not commited. The result was that a reused thread that had called that method before would throw a nested exception. By commiting the transaction the problem was solved :)
You aren't using openSession and getCurrentSession properly.
public static SessionFactory getSessionFactory() {
//reabrimos la sesion si esta cerrada al liberar los recursos
//change this: if(sessionFactory.isClosed()) to this:
if(sessionFactory == null || sessionFactory.isClosed())
{
System.out.println("Reopen session"); // Really setup session factory
//change this: sessionFactory.openSession(); to this:
sessionFactory = buildSessionFactory();
}
return sessionFactory;
}
That's not the problem though, your code there just isn't doing what it's supposed to. You need to change:
hibernate_session = HibernateUtil.getSessionFactory().getCurrentSession();
to
hibernate_session = HibernateUtil.getSessionFactory().openSession();
As per the SessionFactory Javadoc:
Obtains the current session. The definition of what exactly "current" means controlled by the CurrentSessionContext impl configured for use.
It's safe to assume your CurrentSessionContext is not thread safe.
It seems that a transaction is started, and before the transaction gets commited an attempt to start a new transaction is made.
This explains the error message that says that a nested transaction (the second transaction inside the ongoing transaction) is not supported.
This could be caused for example by incorrect error handling, for example starting a transaction, not catching an exception or catch and ignore and then try to begin a second transaction without having done either commit or rollback.
An idiom similar to this one should be used when doing programmatic transaction mananagement:
try {
sess.getTransaction().begin();
// do some work
sess.getTransaction().commit()
}
catch (RuntimeException e) {
sess.getTransaction().rollback();
throw e;
}
Also important to bear mind is that after a rollback the session cannot be reused, as it's in an inconsistent state.
If using a framework like Spring, the use of the annotation #Transactional for declarative transaction management solves most of these problems for us and leads to more maintainable code, EJB3 has also similar functionality.
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.