Monday, August 10, 2020

Java Technical interview @ Thales Group: Round-3

 Hi friends,


In this post, I am sharing interview questions asked in Thales group: round-3. 


Question 1:

What are the differences between save() and persist() methods?

Answer:

  • persist() is defined in JPA. save() is defined in hibernate.
  • persist() return type is void. save() returns serializable object[generated id].
  • persist() doesn't execute insert statement outside transaction boundary. But save() can execute insert statement inside/outside transaction boundary.
  • We can persist detached object using save() and it will crate a new row in the table. We cannot persist  a detached object using persist() and it will throw PersistentObjectException.

Working of persist() method:


When it is called on transient instance, then that instance's state is changed to persistent. No record will be created in DB until until commit or flush is called on session object or session is closed.

When it is called on persistent object, then nothing happens.
When it is called on detached instance, then it throws PersistentException.

persist() method has void return type.

Note: An instance will go to detached state, when evict() is called on session instance, or session is closed.


Example:

Person p = new Person();
p.setName("abcd");
session.persist(p);

//Here when persist() is called, the person object has transitioned from transient to persistent state.

The object is in the persistent context now, but not yet saved to the db. The generation of INERT statement will occur only upon committing the transaction, flushing or closing the session.

Working of save() method:


The save() method is an original hibernate method that does not conform to the JPA specification.
It's purpose is basically the same as persist(), but it has different implementation details.
The documentation for this method strictly states that it persists the instance, "first assigning a generated identifier". The method is guaranteed to return the serializable value of this identifier.

Person p = new Person();
p.setName("abcd");
long id = (long) session.save(p);

The effect of saving an already persisted instance is the same as with persist(). Difference comes when we try to save a detached instance.

Person p = new Person();
p.setName("abcd");
long id = (long) session.save(p);

session.evict(p);
long id2 = (long)session.save(p);


The id2 variable will differ from id1. The call of save() on a detached instance creates a new persistence instance and assigns it a new identifier, which results in a duplicate record in a database upon committng or flushing.



Working of update() method:

As with persist and save, the update method is an “original” Hibernate method that was present long before the merge method was added. Its semantics differs in several key points:

  • it acts upon passed object (its return type is void); the update method transitions the passed object from detached to persistent state;
  • this method throws an exception if you pass it a transient entity.

 

import org.hibernate.*;

import org.hibernate.cfg.*;

 

public class ClientLogicProgram{

 

public static void main(String... args)

{

 

        Configuration cfg = newConfiguration();

cfg.configure("hibernate.cfg.xml");

 

SessionFactoryfactory = cfg.buildSessionFactory();

 

        Session session1 = factory.openSession();

         Product p=null;   //Transient state..

         Object o=session1.get(Product.class, new Integer(1001));

         p=(Product)o;   //now p is in Persistent state..

 

        session1.close();

 

 

p.setPrice(36000);            // p is in Detached state

 

        Session session2=factory.openSession();

         Transaction tx=session2.beginTransaction();

            session2.update(p);   // now p reached to Persistent state

tx.commit();

 

        session2.close();

factory.close();

}

}


 

Question 2:

What are spring transaction isolation levels?

Answer:


Isolation level defines how the changes made to some data repository by one transaction affect other simultaneous concurrent transactions. And also how and when that changed data becomes available to other  transactions.


When we define a transaction using the spring framework , we are also able to configure in which isolation level that same transaction will be executed.


Usage example:


Using the @Transactional annotation, we can define the isolation level of a spring managed bean transactional method. This means that the transaction in which this method is executed will run with that isolation level.


Isolation level in a transactional method:

@Autowired

private TestDAO testDAO;

@Transactional (isolation = Isolation.READ_COMMITTED)

public void someTransactionalMethod(User user){

    // interact with testDAO

}


READ_UNCOMMITTED:


READ_UNCOMMITTED isolation level states that a transaction may read data  that is still uncommitted by other transactions. This constraint is very relaxed in what matters to transactional concurrency , but it may led to some issues like dirty reads. 




Note: READ_UNCOMMITTED is also vulnerable to non-repeatable reads and phantom reads.


READ_COMMITTED:


This level states that  a transaction cannot read data that is not yet committed by other transactions.

This means that dirty read is no longer an issue , but even this way other issues may occur.






In this example Transaction A reads some record. Then Transaction B writes that same record and commits. Later Transaction A reads that same record again and may get different values because Transaction B made changes to that record and committed. This is a non-repeatable read.

Note: READ_COMMITTED is also vulnerable to phantom reads.

 

 

REPEATABLE_READ

REPEATABLE_READ isolation level states that if a transaction reads one record from the database multiple times the result of all those reading operations must always be the same. This eliminates both the dirty read and the non-repeatable read issues, but even this way other issues may occur. 




In this example Transaction A reads a range of records. Meanwhile Transaction B inserts a new record in the same range that Transaction A initially fetched and commits. Later Transaction A reads the same range again and will also get the record that Transaction B just inserted. This is a phantom read: a transaction fetched a range of records multiple times from the database and obtained different result sets (containing phantom records).



SERIALIZABLE:

This is the most restrictive of all isolation levels. Transactions are executed with locking at all levels (read, range and write locking) so they appear as if they were executed in a serialized way.

This leads to a scenario where none of the issues mentioned above may occur. But in the other way, we do not allow transaction concurrency and consequently introduce a performance penalty.



That's all for this post.

Thanks for reading!! 



No comments:

Post a Comment

CAP Theorem and external configuration in microservices

 Hi friends, In this post, I will explain about CAP Theorem and setting external configurations in microservices. Question 1: What is CAP Th...