Wednesday, October 5, 2016

First Level Cache in Hibernate

Caching is a mechanism for storing the loaded objects into cache memory. The advantage of this is, whenever we want to load the same object from the database, instead of hitting the database once again, it loads from the local cache memory, so that the no. of round trips between an application and the database gets reduced.

Caching mechanism increases the performance of the application.

In hibernate we have two levels of caching
First Level Cache [Session Cache]
Second Level Cache [Session Factory Cache or JVM Level Cache]


By default, for each hibernate application, the first level cache is automatically enabled and we cannot disable it.

First level cache is associated with the session and its scope is limited to one session only.

When we load an object for the first time from the database, the object gets loaded from the database and stored in the cache memory.

If we load the same object once again in the same session, then the object will be loaded from the local cache memory instead of the database.

If we load the same object by opening another session, then again the object will be loaded from the database and stored in the cache memory of this new session.

Example:
1)Session session1 = factory.openSession();
2)Object obj1 = session1.get(Emp.class, new Integer(101));

3)Object obj2 = session1.get(Emp.class, new Integer(101));
4)Object obj3 = session1.get(Emp.class, new Integer(101));

5)session.close();

6)Session session2 = factory.openSession();
7)Object obj4 = session2.get(Emp.class, new Integer(101)); 

In the above example, object will be loaded from the database at line number 2.

But at line number 3 and 4 it will be loaded from the cache.

Again at line number 7 object is loaded from the database since its a new session.

Sunday, October 2, 2016

Dirty loading/checking in Hibernate

Every Hibernate session is cached.

It caches entities read from the database, changes made to entities, as well as added and removed entities; until the session is flushed (ie written to the database).

A session is said to be dirty when some changes have not yet been flushed. This session is flushed before the transaction is committed. It is perfectly normal to have a dirty session.

In simple words: Dirty data is the one which is not yet committed. Similarly, dirty session in hibernate contains modified data which is not yet committed :)

Configuration con = new Configuration();
con.configure("dirty.cfg.xml");
SessionFactory sf = con.buildSessionFactory();
Session session = sf.openSession();
Transaction trans = session.beginTransaction();

try
{
   Gender gender = (Gender)session.get(Gender.class, new Long(1));
   gender.setName("someName");
   session.getTransaction().commit();
   session.flush();
}
catch(Eception ex)
{
  ex.printStackTrace();
}

Here, we have not called update(), even then object state is written to the database. This is called automatic dirty checking

Hibernate monitors whether any changes are made in the session object and automatically synchronizes them to the database.

session.getTransaction.commit() is mandatory, else correct data will not reflect in the database.

Cascade and Inverse in Hibernate

In case of many-to-many relationship via intermediary table, CASCADE says whether a record will be
created/updated in the child table and INVERSE says whether a record will be created/updated in the
intermediary table

Example:
One student can have multiple phones, so Student class has property for Set of phones.
One Phone can be owned by multiple students, so Phone class has property for Set of Students.

This mapping is maintained in STUD_PHONE table.

So there are three tables -> STUDENT, PHONE and STUD_PHONE (intermediary) table.

Mapping might look like:

<set name="phoneset" table="stud_phone" cascade="save-update" inverse="true">
  <key column="mapping_stud_id">< /key>
  <many-to-many class="com.domain.Phone" column="mapping_phon_id"/>
</set> 

A new student object is created and 2 new phone objects are added to its set.
Now after calling session.save(student_obj) , depending upon CASCADE and INVERSE settings different queries will be fired.

Below are the different combinations->

1) CASCADE IS NONE and INVERSE is false

insert into STUDENT (Name, stud_id) values (?, ?)
insert into STUD_PHONE (mapping_stud_id, mapping_phon_id) values (?, ?)
insert into STUD_PHONE (mapping_stud_id, mapping_phon_id) values (?, ?)

2) CASCADE is NONE and INVERSE is true

insert into STUDENT (Name, stud_id) values (?, ?)

3) CASCADE is save-update and INVERSE is false

insert into STUDENT (Name, stud_id) values (?, ?)
insert into PHONE(phone_num, phone_id) values (?, ?)
insert into PHONE(phone_num, phone_id) values (?, ?)
insert into STUD_PHONE (mapping_stud_id, mapping_phon_id) values (?, ?)
insert into STUD_PHONE (mapping_stud_id, mapping_phon_id) values (?, ?)

4) CASCADE is save-update and INVERSE true

insert into STUDENT (Name, stud_id) values (?, ?)
insert into PHONE(phone_num, phone_id) values (?, ?)
insert into PHONE(phone_num, phone_id) values (?, ?)

Thus only when CASCADE was save-update the records were created in PHONE table, otherwise not.

When INVERSE is false (Student is the owner of relationship) the intermediary table STUD_PHONE was updated.

When INVERSE  is true (Phone is owner of relationship), so even though a new student was created, the intermediary table was not updated.

So in case of relation of two entities, CASCADE affects other entity table and INVERSE  affects intermediary table. So their effect is independent.

Saturday, September 24, 2016

Remove Special Characters, Tabs, New Lines, Spaces and HTML Tags in SQL

We come across situations where we need to remove HTML tags , New Lines, Tabs and Spaces from a database column. Also we need to allow/disallow some special characters.

This can be achieved through the following SQL queries->


Remove HTML tags->

SELECT REGEXP_REPLACE(memotext,'<[^>]*>','') FROM TB_CITIALERTS_MEMO;



Remove new line(\n) and tabs(\t) ->

SELECT REPLACE(REPLACE(memotext,CHR(10),''),CHR(13),'') FROM TB_CITIALERTS_MEMO;

CHR(10) = New Line
CHR(13) = TAB



Replace Multiple spaces by Single space ->

SELECT REGEXP_REPLACE(memotext,'( ){2,}', ' ') FROM TB_CITIALERTS_MEMO;

The above query replaces more than 1 space by a single space.



Allow some special characters ->

SELECT REGEXP_REPLACE(memotext,'[^0-9a-zA-Z&@~_!|#$%*;,(){}/\. []') FROM TB_CITIALERTS_MEMO;

The above query allows those special characers that are included in this list [^0-9a-zA-Z&@~_!|#$%*;,(){}/\. []'), here you can omit the ones that you dont want to show.



We can also combine everything together as shown below ->

SELECT REGEXP_REPLACE(REPLACE(REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(memotext,'<[^>]*>',''),'( ){2,}', ' '),CHR(10),''),CHR(13),''),'[^0-9a-zA-Z&@~_!|#$%*;,(){}/\. []') memotext
FROM TB_CITIALERTS_MEMO;

Tuesday, June 21, 2016

Restrict direct access to JSP's in your application

If you want to restrict users from directly accessing JSP's in your application , like when users directly type the url of the JSP in the browser without logging in.

In this scenario you have 2 options ->

Option 1) Put all JSP's under WEB-INF folder.

Option 2) Write the following code in web.xml file.

<security-constraint>
        <web-resource-collection>
            <web-resource-name>JSP Files</web-resource-name>
            <description>No direct access to JSP files</description>
            <url-pattern>*.jsp</url-pattern>
            <http-method>POST</http-method>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description>No direct browser access to JSP files</description>
            <role-name>NobodyHasThisRole</role-name>
        </auth-constraint>
  </security-constraint>

Note: In the above code snippet you need to give the exact location of your JSP's ->  
<url-pattern>*.jsp</url-pattern> 
or 
<url-pattern>/Folder Name/*.jsp</url-pattern>
Home