I was trying to mock hibernate session. This is the code snippet I tried:
#Before
public void setUp() {
campaignModel = DraftTestHelper.buildDraftModel();
if(sessionFactory != null) {
System.out.println("Session Factory not null");
}
else
System.out.println("Session Factory is null");
session = sessionFactory.getCurrentSession();
if(session != null) {
System.out.print("Not null");
}
else
System.out.println("Null");
}
Mock Code:
#Mock
SessionFactory sessionFactory;
#InjectMocks
DraftCampaignModelBuilder draftBuilder;
private DraftCampaignModel campaignModel;
private Session session;
According to console, session factory is not null. But hibernate session is null. Can anyone please help on this?
Thanks
I think you need to write this in your #Before method:
when(sessionFactory.getCurrentSession()).thenReturn(hibernateSession);
e.g.
#Mock
private HibernateSession hibernateSession;
#Before
public void setUp() {
when(sessionFactory.getCurrentSession()).thenReturn(hibernateSession);
campaignModel = DraftTestHelper.buildDraftModel();
if(sessionFactory == null) {
System.out.println("Session Factory is null");
}
else {
System.out.println("Session Factory is not null");
session = sessionFactory.getCurrentSession();
if(session != null) {
System.out.print("Session is not null");
}
else {
System.out.println("Session is null");
}
}
}
Related
I keep waking up the morning to my site being down because of this No operations allowed after connection closed.
here is the getSession method we use :
public static Session getSession() throws HibernateException {
Session session = THREAD_LOCAL.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
THREAD_LOCAL.set(session);
}
return session;
}
Here is the closeSession
public static void closeSession() throws HibernateException {
Session session = (Session) THREAD_LOCAL.get();
THREAD_LOCAL.set(null);
if (session != null) {
if (session.isOpen()) {
session.close();
}
}
}
here is the configureSessionFactory
private static SessionFactory configureSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
} catch (HibernateException e) {
e.printStackTrace();
}
return sessionFactory;
}
Here is one of our Dao function
public Client getClientInformation(int client_id) {
final Session session = HibernateUtil.getSession();
Client client = null;
try {
session.beginTransaction();
Query q = session.createQuery("FROM Client c WHERE c.id = :client_id")
.setInteger("client_id", client_id);
if (q.list().size() > 0) {
client = (Client) q.uniqueResult();
}
if (session.isOpen()) {
session.close();
}
} catch (HibernateException e) {
} finally {
HibernateUtil.closeSession();
}
return client;
}
In my application i have a situation where i need to do a recursive call to a method to achieve requirement.
But when i call the method I am getting
_Exception in thread "main" org.hibernate.SessionException: Session was already closed
at org.hibernate.internal.SessionImpl.close(SessionImpl.java:410)
at com.cerner.core.dao.oracleImpl.test.TestRecurssionSessionClose.fact(TestRecurssionSessionClose.java:40)
at com.cerner.core.dao.oracleImpl.test.TestRecurssionSessionClose.main(TestRecurssionSessionClose.java:49)
_
I have test code for this
public class TestRecurssionSessionClose {
private SessionFactory factory;
private Session session;
private Transaction transaction;
public TestRecurssionSessionClose() {
HibernateUtil.configureSessionFactory();
factory = HibernateUtil.getFactory();
}
public int fact(int n) {
System.out.println(factory.isClosed());
session = factory.openSession();
transaction = session.beginTransaction();
try {
if (n == 1) {
return 1;
} else {
System.out.println(n);
return (n * fact(n - 1));
}
} catch (
HibernateException ex) {
if (transaction != null)
transaction.rollback();
return 0;
} finally {
if (session != null) {
session.close();
}
}
}
public static void main(String[] args) {
TestRecurssionSessionClose testRecurssionSessionClose = new TestRecurssionSessionClose();
System.out.println(testRecurssionSessionClose.fact(3));
}
}
I am new to hibernate. please tell me what I am missing here?
By default some hibernate versiones have hibernate.transaction.auto_close_session to true. This makes that the session is closed automatically without requirement to close.
Disable the auto close session or better use automatic session context management
See: Session configuration
Sorry for my english. I learn JavaEE and i dont know proper or not i use session in hibernate. How to use them? I use pattern DAO and hibernate. Tell my how property use session
this is HibernateUtil class
private static final SessionFactory sessionFactory;
static {
try{
sessionFactory = new Configuration().configure("/app/web/landingpage/HibernateConnect/hibernate.cfg.xml").buildSessionFactory();
}catch(Throwable ex) {
System.out.println("Error " + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void close(Session session) {
if (session != null) {
try {
session.close();
} catch (HibernateException ignored) {
System.out.print("Couldn't close Session" + ignored);
}
}
}
And that class makes all operation db CategoryDaoImpl
public class CategoryDaoImpl implements CategoryDao{
private Session session = null;
//get all category
public Collection getAllCategory() {
List categoris = new ArrayList<Category>();
try{
session = HibernateUtil.getSessionFactory().openSession();
categoris = session.createCriteria(Category.class).list();
}catch(Exception e) {
System.out.println("getAllCategory "+ e);
}finally{
if(session != null && session.isOpen())
session.close();
}
return categoris;
}
//get category id
public Category getCategory(int id) {
Category cat = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
cat = (Category) session.load(Category.class, id);
}catch(Exception e) {
System.out.println("getAllCategory "+ e);
}finally{
if(session != null && session.isOpen())
session.close();
}
return cat;
}
//and below few methods that use it the some way session
}
and this servlet take results indexuser
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
try{
Collection allcategory = Factory.getInstance().getCatDAO().getAllCategory();
request.setAttribute("allcategory", allcategory);
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch(Exception e) {
System.out.println(e);
} finally{
if(session!=null && session.isOpen())
session.close();
}
The main contract here is the creation of Session instances. Usually an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory.
The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.
Basically session is used to get physical connection with database. So while you performing any DB Operations it will first open Session using sessionFactory and then Session do physical connection with database and then perform your operation and after performing operation you can close it.
Session is light weight.
In our application we have an HibernateSessionFactory class, that is opening and closing connections. Everything is okay, but when we are updating data in the database, it doesn't change in our application. Unfortunately, we see old data from the database. How can I fix this?
public class HibernateSessionFactory {
private static final ThreadLocal threadLocal = new ThreadLocal();
private static org.hibernate.SessionFactory sessionFactory;
private static Configuration configuration = new Configuration();
private static ServiceRegistry serviceRegistry;
private static final Logger log = Logger.getLogger(
HibernateSessionFactory.class);
static {
try {
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
log.error("Error Creating SessionFactory", e);
}
}
private HibernateSessionFactory() {}
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ?
sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
log.error("Error Creating SessionFactory", e);
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.flush();
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Configuration getConfiguration() {
return configuration;
}
}
.
#SuppressWarnings("unchecked")
public List<Tauthor> getAuthors() throws HibernateException {
log.debug("getting all authors");
Query queryObject = null;
List<Tauthor> authors = null;
Session session = HibernateSessionFactory.getSession();
try {
String queryString = "from Tauthor";
queryObject = session.createQuery(queryString);
authors = queryObject.list();
} catch (HibernateException e) {
log.error("get all authors failed", e);
throw e;
} finally {
HibernateSessionFactory.closeSession();
}
return authors;
}
You haven't shared your code where you write data to the database. Without that, I can think of only a few reasons as to why your data output is old instead of new data:
Your transactions are not being committed.
Hibernate hasn't written to the database at the time of data queried by you.
Hibernate's cache hasn't been updated, which results in query returning old data.
You should verify that data has been written to the Database with a db developer tool and try disabling all hibernate caching to see if the result changes.
I have create a dbadapter for delaing with hibernate.Actually my class looks like this..
public class DBAdapter {
private static SessionFactory factory;
private static final ThreadLocal<Session> threadSession = new ThreadLocal();
public static Session OpenConnection() {
if (factory == null) {
factory = new Configuration().configure(
"com/et/hibernatexml/hibernate.cfg.xml")
.buildSessionFactory();
}
Session s = (Session) threadSession.get();
if (s == null)
{
s =factory.openSession();
threadSession.set(s);
}
return s;
}
public List selectQuery(String QueryString)
{ try
{
Session session=OpenConnection();
resultlist = query.list();
}
finally()
{
closeSession();
}
}
public static void closeSession()
{
Session session = (Session) threadSession.get();
threadSession.set(null);
if (session != null && session.isOpen()) {
session.flush();
session.close();
}
}
For getting data from server ,i will do like this..
DBAdapter ob=new DBAdapter();
ob.setParameter("orgId", orgId);
List list=ob.selectQuery(queryvalue);
My doubt is any issue by dealing like this.Especially because SessionFactory is static variable??
You do not want more than one threads to create a session factory. It should be a singleton and is by design thread safe. The easiest way to do this with the code you provided is to use the synchronized keyword on the openConnection() method. However, there is no reason to synchronize the part of the code where you create a session and put it on the ThreadLocal instance as well. A rough solution would be like the following
public class DBAdapter {
private static SessionFactory factory;
private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
private static synchronized SessionFactory getSessionFactory() {
if(factory == null) {
factory = new Configuration().configure("com/et/hibernatexml/hibernate.cfg.xml").buildSessionFactory();
}
return factory;
}
public static Session getSession() {
Session s = (Session) threadSession.get();
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
return s;
}
}