Hibernet Select Query empty constraint - java

Am using hibernate query to select group of data from the table. Result set of the select query is stored in to List. Query is executing correctly. Even if the query return a empty selection how can i check the List is empty or not..Based on the condition the transaction get executed.
How can i check List is empty or not?
public String getData(String ID){
Transaction transaction=null;
Session session=HibernateUtil.getSessionFactory().openSession();
List<MyClass> myList=null;
try{
transaction=session.beginTransaction();
myList=session.createQuery("from table as t where t.ID=:ID")
.setString("ID",ID).list();
transaction.commit();
}catch(RuntimeException e){
if(transaction!=null){
log.error(e);
transaction.rollback();
}
}finally{
session.flush();
session.close();
}
}

How can i check List is empty or not?
Use isEmpty method.
if(myList.isEmpty()){
// List is empty.
}

There is a function to check whether list contains records or not called isEmpty()
myList.isEmpty(); //return booleans based on your myList.
Have a look at this doc.

`Based on the condition the transaction get executed.`
if Your transaction executed successfully then only you will get the List as empty otherwise your list will be null because you have initialised it with null
So if the transaction is completed then you can use the isEmpty() or the list.size() method to check the size
List<MyClass> myList=null; **// initialised as null**
try{
transaction=session.beginTransaction();
myList=session.createQuery("from table as t where t.ID=:ID")
.setString("ID",ID).list();
transaction.commit(); **// if any exception comes myList will be null**
}catch(RuntimeException e){
if(transaction!=null){
log.error(e);
transaction.rollback();
}
}finally{
session.flush();
session.close();
}

Related

Hibernate not getting changes from database even I turn off the session everytime and turn off the 2nd level cache

I have a hibernate fetch as follows (it is called by a synchronized method in threads). The problem is if I updated the status_id to 1 in the DB console, the code won't pick it up. And when I run the sql Hibernate show_sql printed out in the console, it can find one record. Moreover, I can see the select sql being run every time via show sql.
To make the problem clear, if I update the record status to 1 and then start the application, the code will return me one record and after processing, the record status will be updated to 2. As I expected, after that, the code will return nothing cause the status being updated to 2. However, if I manually update the status to 1, it won't pick it up.
As you can see from the configuration, I have already turn off the 2nd level cache and every time, I close the session. I am using Enum to define the Hibernate connection. So the sessionFactory is always the same instance. I don't know if this matters but I assume that is what it should be.
The dao code is
Session session = null;
String sql = "from MyEntity rr where status_id = 1;"
try {
session = getSessionFactory().openSession();
Query q = session.createQuery(sql);
q.setMaxResults(1);
List resultList = q.list();
if (resultList.isEmpty())
return null;
return (MyEntity) resultList.get(0);
} catch (Exception e) {
LOGGER.error(e.getMessage());
} finally {
if (session != null) {
session.close();
}
}
return null;
The code to update the status is
Session session = null;
try {
session = getSessionFactory().openSession();
session.beginTransaction();
session.update(myEntity);
session.flush();
session.getTransaction().commit();
} catch (Exception e) {
LOGGER.error(e.getMessage());
} finally {
if (session != null) {
session.close();
}
}
If the entity doesn't exist, you need to invoke save() on it, otherwise you need to invoke update(), it will modify the existing persistent object in database.
Be aware everytime invoke save() would insert a new row in database. You may use saveOrUpdate() to achieve above save() and update() actions, Hiberate will either call save or update depends on the situation and take care of it.
You can invoke flush() after each saveOrUpdate() which forces Hibernate execute save or update in your database.
I found the solution. Once I put the transaction on fetch, it start to work. Don't know why. Any one can give some explaination? Thanks.

Hibernate Save Java Collection in a single shot

We use Hibernate 5 and we need to persist upto 1 million of records every day, right now code we use is
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
try
{
session.getTransaction().begin();
for (CustomObject customObject : CustomObjectList)
{
session.save(customObject);
}
log.info("Saved all entities in Hibernate Session");
session.getTransaction().commit();
}
catch (HibernateException e)
{
log.error("HibernateException :{}", e.getMessage(), e);
session.getTransaction().rollback();
session.clear();
}
finally
{
HibernateUtil.closeSession(session);
}
Here CustomObject is my Table Entity, so my CustomObjectList contains 1 million records and persisting into Database using default bulk insert property
Can we persist all list values in a single shot instead of iterating , What is the best way to improve performance?
Is Something like session.save(customObjectList) possible?

Hibernate update is sometimes not working

I have a requirement where I am updating rows according to uuid's where one uuid may be associated to more than one rows.
Here's the scenario:
4a90558c-4a5b-4af7-8c68-60ff81f74ef3 is my uuid and it exists in 8 columns in my DB.
and my java code is as follows:
try{
session = sessionFactory.getCurrentSession();
tx = session.getTransaction();
criteria = session.createCriteria(Archive.class);
criteria.add(Restrictions.eq("bagUuid", "4a90558c-4a5b-4af7-8c68-60ff81f74ef3"));
ScrollableResults items = criteria.scroll();
while ( items.next() ) {
Archive archive = (Archive)items.get(0);
archive.setDecision(1);
archive.setOperatorAssigned("test");
session.saveOrUpdate(archive);
session.flush();
session.clear();
}
tx.commit();
LOGGER.info("Archive Record is updated: "+archive.getFilePath());
}catch(Exception e){
recordUpdated = false;
tx.rollback();
LOGGER.error("Archive Record failed to update due to exception in updateArchiveRecord method: "+e.getMessage());
}
Here sometimes all records associated to UUID is updating but sometimes failing.
I think it may be a issue with the Hibernate API.
Does anybody else has faced the same issue.
This line looks suspicious:
Archive archive = (Archive)items.get(0);
It means thart regardless of the number of items in the ScrollableResults, you will be updating only the first Archive object. If I understood what you are trying to do correctly, it should be a current record:
Archive archive = (Archive)items.get();
Also, I'd move out/delete session.flush() and session.clear(). The final code would look like this:
try{
session = sessionFactory.getCurrentSession();
tx = session.getTransaction();
criteria = session.createCriteria(Archive.class);
criteria.add(Restrictions.eq("bagUuid", "4a90558c-4a5b-4af7-8c68-60ff81f74ef3"));
ScrollableResults items = criteria.scroll();
while ( items.next() ) {
Archive archive = (Archive)items.get();
archive.setDecision(1);
archive.setOperatorAssigned("test");
session.saveOrUpdate(archive);
}
tx.commit();
session.close();
LOGGER.info("Archive Record is updated: "+archive.getFilePath());
}catch(Exception e){
recordUpdated = false;
tx.rollback();
LOGGER.error("Archive Record failed to update due to exception in updateArchiveRecord method: "+e.getMessage());
}
Slava Imeshev

Best way to get Session and Release session in HIbernate/SQL

Consider the below two codes.
Session session = null;
query = "update Employee set EMPLOYEE_NAME = 'Jay' where EMPLOYEE_ID = 1";
try {
session = getSession();
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(session != null) {
releaseSession(session);
}
}
And....
Session session = getSession();
query = "update Employee set EMPLOYEE_NAME = 'Jay' where EMPLOYEE_ID = 1";
try {
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(session != null) {
releaseSession(session);
}
}
Which among the two is better to use? Or is there a better way? What wrong I might be doing here?
Also should we do a null check before calling releaseSession(session) in finally?
Truly, the best way is to leverage Spring and its JPA/Hibernate support.... You'll never have to deal with it in your code.
To be honest, I'd say there wasn't much difference at all in the two, but you should always check if the session is null, just so you don't cause another NullReferenceException.
Unfortunately this is probably the cleanest way to do this in Java, as there is no such thing as the "using" statement as there is in C#, which allows you to dispose the object after the using block has finished executing.
I would suggest using a transaction. If tomorrow you change your code to add another update for instance, you won't have to worry about any consistency problem in case something happens while executing an update. Aside from that, I would suggest using parameters in your query rather than hard-coding the values. This way you could reuse the query.
If getSession() throws an Exception for some reason, would not it be problem in second solution?
Use the below syntax to get and release session.
session = getSession();
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
session.close();

Why session.createCriteria(classtype).list() return more object than in list?

Why session.createCriteria(classtype).list() return more object than in list?
Returned list is contains repeating objects in random order.
public Collection getAll() {
List list = null;
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
list = session.createCriteria(getClassType()).list();
tx.commit();
} catch (HibernateException ex) {
if (tx != null) {
tx.rollback();
}
LOGGER.error("HibernateException in getAll");
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
return list;
}
I'm assuming your session.createCriteria(classtype).list() call is returning some of the objects of this class multiple times.
This can occur when you have a OneToMany or ManyToMany relation that is eagerly fetched.
One way to solve this, as JB Nizet correctly points out, is to use the Criteria.DISTINCT_ROOT_ENTITY ResultTransformer.
This, however, will do the work at the 'java side': all objects will be fetched from the database and then all duplicates are removed.
It would be much better to make the OneToMany or ManyToMany lazy (which is the default) instead of eager.
It's probably because the loaded entity has a toMany association that is eagerly fetched using a join. Use a distinct root entity result transformer to only get each root entity once in the list:
criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
or return a Set rather than a List if the order is not important.
Thanks for help, i used it, and resolve problem this way:
...
try {
session = HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(getClassType())
.setProjection(Projections.id())
.setFirstResult(getStart())
.setMaxResults(getLength());
HashSet<Long> ids = new HashSet( criteria.list() );
criteria = session.createCriteria(getClassType())
.add(Restrictions.in(ID_COLUMN_NAME, ids))
TreeSet<Employee> items = new TreeSet( criteria.list() );
list = new ArrayList<Employee>(items);
tx.commit();
} catch (HibernateException ex) {
...

Categories