Need to understand transaction.factory_class of Hibernate configuration - java

In my hibernate.cfg.xml file, one of the properties is -
<property name = "transaction.factory_class"> <!--1-->
org.hibernate.transaction.JDBCTransactionFactory <!--2-->
</property> <!--3-->
Other properties are easy to understand. But, many questions came to my mind when I saw the above property.
line 1 - this specifies the class implementing the Transaction*Factory* interface.
Q1 - I saw the java docs for TransactionFactory but did not understand what it really is. What does this "Factory" mean ? Why don't they call it TransactionGenerator as per the line -
Contract for generating Hibernate Transaction instances.
Q2 - TransactionFactory lead me to Transaction. Is this exactly the same as a Database transaction ?
Q3 -
A single session might span multiple transactions since the notion of
a session (a conversation between the application and the datastore)
is of coarser granularity than the notion of a transaction. However,
it is intended that there be at most one uncommitted Transaction
associated with a particular Session at any time.
...the notion of a session is of coarser granularity than the notion of a transaction.
What does that mean in simple words ?
--
However, it is intended that there be at most one uncommitted
Transaction associated with a particular Session at any time.
Why do you intend this ?
I don't think that the API docs are clear. Makes a n00b life miserable.

Q1 - The reasoning is clear. The transaction creation follows a factory pattern. For example, in an environment where application servers (like JBOSS, WebSphere etc) manage the transaction creation via JTA APIs, you will use a JTA Transaction factory to create transactions and that transactions will be further used by hibernate. In a purely Spring managed environment, Spring can be configured to use a HibernateTransactionFactory. In short, it would follow a similar fashion as:
IFactory f= FactoryCreatorForYourEnvironment.create();
Transaction t = f.create();
Q2 and Q3 - Yes, a hibernate transaction factory creates database transactions on underlying DB. Note that a session may be spanning over multiple transactions - A hibernate session abstracts a database connection. Over the same connection, multiple begin transaction, commit transaction cycles are possible. Example: REQUIRE_NEW properties if the participating beans (EJBs, or SPRING beans). So session is a broader (coarser) term as mentioned in the documentation.
Transactions are required for any writes, deletes, protected reads. So the session holds an implicit transaction. You can read a related stack overflow article here.
HTH.

Related

JTA for single database

I am just learning JTA and can't understand if I should use it if I have only one database. Currently I use hibernate 5 as JPA provider and if I need to use one transaction between methods I just pass EntityManager as argument.
However, I don't like this method as I need to remember if transaction is opened or not. I would like to find any library that will help me to control transactions (but without Spring) in SE environment. So, should I use JTA in my situation or should I use something different?
Normally when talking about JTA , it refers to the distributed transaction across multiple systems (e.g. across two databases , one database and one JMS compliant message broker). If you only have one database , it is not necessary to use JTA transaction although it should also work. Instead, use a local transaction for one database which should theoretically faster than using JTA transaction.
On the other hands , if you are just talking about #Transactional defined in the JTA , which allow you to declaratively control the transaction boundary by annotating it on a method and without passing the EntityManager between methods , you should look into which frameworks support it.
Under the cover , a proxied EntityManager is injected into different classes such that when it is invoked , it will get the actual EntityManager from the ThreadLocal. So every class in the same thread will get the same EntityManager which prevent you from passing the EntityManager around the methods. A new EntityManager instance will be set to the ThreadLocal just before the #Transactional method is executed using some sort of AOP technique.
Please note that #Transcational is nothing to do with the underlying transaction is JTA or local transaction. It should work for both transaction type.
I would use a framework that support #Transactional such as Spring , Quarkus or Micronaut etc , and configure Hibernate to use local transaction but not JTA transaction for single database.

Locking all the rows used in the Transaction Java

I have a scenario where I use a read on set of tables in a java service.
I've annotated the service class #Transactional.
Is there any possible way to lock the corresponding rows I read, in all the tables I use, in my transaction and release it at the end of transaction ?
Ps: I'm using spring Hibernate, and I'm new to this locking concept.
any material/ examples links would be of much help
Thanks
This depends on the underlying database engine and selected transaction isolation level.
Some database systems do locking for reads, and some use MVCC, which means your updates won't be visible to other transactions until your transaction finishes and your transaction will operate on a snapshot of data taken at the start of the transaction.
So a simple answer is: choose appropriately high transaction isolation level (e.g. SERIALIZABLE) for your needs and a database engine that supports it.
http://en.wikipedia.org/wiki/Isolation_(database_systems)

What is a database session?

I understand a general understanding of the concept of a database transaction. We access a database within transaction to ensure ACID properties.
In Hibernate there is a concept called a session. What is the use of a session? When should database access happen in two sessions rather than in the same session?
To explain more, I have seen hibernate code that
gets a session from a session factory
opens a session
begins a transaction
commits the transaction
closes the session
What I need to know is what is the importance of a session here? Why not have something like a transaction factory, begin transaction and commit transaction?
Session is more than just a transaction, it is an implementation of UnitOfWork pattern. In other words it holds on to the loaded objects, knows which objects has to be persisted etc:
A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.
To better understand relation between Session and Transaction you can take a look at this article.
A single Hibernate Session might have the same scope as a single database transaction.
This is the most common programming model used for the session-per-request implementation pattern. A single Session and a single database transaction implement the processing of a particular request event (for example, a Http request in a web application). Do never use the session-per-operation anti-pattern! (There are extremely rare exceptions when session-per-operation might be appropriate, you will not encounter these if you are just learning Hibernate.)
Another programming model is that of long Conversations, e.g. an application that implements a multi-step dialog, for example a wizard dialog, to interact with the user in several request/response cycles.
One way to implement this is the session-per-request-with-detached-objects pattern. Once persistent objects are considered detached during user think-time and have to be reattached to a new Session after they have been modified.
The session-per-conversation pattern is however recommended. In this case a single Session has a bigger scope than a single database transaction and it might span several database transactions. Each request event is processed in a single database transaction, but flushing of the Session would be delayed until the end of the conversation and the last database transaction, to make the conversation atomic. The Session is held in disconnected state, with no open database connection, during user think-time. Hibernate's automatic optimistic concurrency control (with versioning) is used to provide conversation isolation.
#Dmitry has answered very nicely.
Another way to look at the session is as Instance of Database Usage. When you create a session, you have a context ready for any database interaction with support services (e.g. transaction, caching, connection etc) required therein. A transaction is an independent service used within the session.
Also the session is the first level cache used by the typical OR mapping tools like hibernate. Session acts as temporary context created upon request to facilitate a DB interaction.

Spring-Hibernate used in a webapp,what are strategies for Thread safe session management

I'm developing a web app with Spring and Hibernate and I was so obsessed by making he application thread safe and being able to support heavy load that based on my boss recommendation I end up writing my own session and a session container to implement a session per request pattern. Plus I have a lot of DAOs and me not willing to write the same save method for all the DAOs I copy paste this Hibernate GenericDAO (I can't tell it's the same thing because at the time hibernate wasn't owned by jboss) and do the plumbing stuff, and under pressure, all become quickly complicated and on production, the is StaleObjectException and duplicated data right, and i have the feeling that it's time to review what I've done, simplify it and make it more robust for large data handling. One thing you should know is that one request involves many DAO's.
There is quartz running for some updates in the database.
As much as I want to tune everything for the better I lack time to do the necessary research plus Hibernate is kind of huge (learning).
So this is it, I'll like to borrow your experience and ask for few question to know what direction to take.
Question 1 : is Hibernate generated uuid safe enough for threading environment and avoiding StaleObjectException?
Question 2 what are best strategy to use hibernate getCurrentSession in threadSafe scenario (I've read about threadlocal stuff but didn't get too much understanding so didn't do it)
Question 3 : will HIbernateTemplate do for the simplest solution approach?
Question 4 : what will be your choice if you were to implement a connection pool and tuning requirement for production server?
Please do no hesitate to point me to blogs or resources online , all that I need is a approach that works for my scenario. your approach if you were to do this.
Thanks for reading this, everybody's idea is welcomed...
I'm developing a web app with Spring and Hibernate and I was so obsessed by making he application thread safe and being able to support heavy load that based on my boss recommendation I end up writing my own session and a session container to implement a session per request pattern.
You should just drop all this code and use Spring/Hibernate APIs instead: less bugs, less maintenance.
I copy paste this Hibernate GenericDAO (I can't tell it's the same thing because at the time hibernate wasn't owned by jboss) and do the plumbing stuff, and under pressure, all become quickly complicated (...)
You can use a GenericDao and inject the required stuff with Spring.
Question 1: is Hibernate generated uuid safe enough for threading environment and avoiding StaleObjectException?
To strictly answer your question, here is what Reference Guide writes about the uuid generator:
5.1.4.1. Generator
...
uuid
uses a 128-bit UUID algorithm to
generate identifiers of type string
that are unique within a network (the
IP address is used). The UUID is
encoded as a string of 32 hexadecimal
digits in length.
So I consider it as safe. But I think your StaleObjectException are unrelated (it's another problem).
Question 2: what are best strategy to use hibernate getCurrentSession in threadSafe scenario (I've read about threadlocal stuff but didn't get too much understanding so didn't do it)
The best strategy is to just use it, sessionFactory.getCurrentSession() will always give you a Session scoped to the current database transaction aka a "contextual session". Again, quoting the Reference Documentation:
2.5. Contextual sessions
Most applications using Hibernate need
some form of "contextual" session,
where a given session is in effect
throughout the scope of a given
context. However, across applications
the definition of what constitutes a
context is typically different;
different contexts define different
scopes to the notion of current.
Applications using Hibernate prior to
version 3.0 tended to utilize either
home-grown ThreadLocal-based
contextual sessions, helper classes
such as HibernateUtil, or utilized
third-party frameworks, such as Spring
or Pico, which provided
proxy/interception-based contextual
sessions.
(...)
However, as of version 3.1, the
processing behind
SessionFactory.getCurrentSession()
is now pluggable. To that end, a new
extension interface,
org.hibernate.context.CurrentSessionContext,
and a new configuration parameter,
hibernate.current_session_context_class,
have been added to allow pluggability
of the scope and context of defining
current sessions.
See the Javadocs for the
org.hibernate.context.CurrentSessionContext
interface for a detailed discussion of
its contract. It defines a single
method, currentSession(), by which
the implementation is responsible for
tracking the current contextual
session. Out-of-the-box, Hibernate
comes with three implementations of
this interface:
org.hibernate.context.JTASessionContext:
current sessions are tracked and
scoped by a JTA transaction. The
processing here is exactly the same as
in the older JTA-only approach. See
the Javadocs for details.
org.hibernate.context.ThreadLocalSessionContext:
current sessions are tracked by thread
of execution. See the Javadocs for
details.
org.hibernate.context.ManagedSessionContext:
current sessions are tracked by thread
of execution. However, you are
responsible to bind and unbind a
Session instance with static methods
on this class: it does not open,
flush, or close a Session.
(...)
There is no need to implement your own ThreadLocal-based solution nowadays, don't do that.
Question 3 : will HIbernateTemplate do for the simplest solution approach?
Well, the HibernateTemplate is not deprecated but it is not recommended anymore and I prefer to implement template-less DAOs:
public class ProductDaoImpl implements ProductDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Collection loadProductsByCategory(String category) {
return this.sessionFactory.getCurrentSession()
.createQuery("from test.Product product where product.category=?")
.setParameter(0, category)
.list();
}
}
Where the SessionFactory is injected by Spring. I suggest to read So should you still use Spring's HibernateTemplate and/or JpaTemplate?? for complete background and also the whole section 13.3. Hibernate in the Spring documentation on ORM Data Access.
Question 4 : what will be your choice if you were to implement a connection pool and tuning requirement for production server?
Hmm... What? I would never implement my connection pool but use the one from my application server. Maybe you should clarify this question.
Update: In production, I wouldn't use Hibernate built-in connection pool but configure Hibernate to use an application server provided JNDI datasource (and thus the application server connection pool). From the documentation:
3.3. JDBC connections
...
Here is an example hibernate.properties file for an application server provided JNDI datasource:
hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
JDBC connections obtained from a JNDI datasource will automatically participate in the container-managed transactions of the application server.

Difference between UserTransaction and EntityTransaction

Title says it all: What is the difference between a UserTransaction and an EntityTransaction?
My rudimentary understanding is that UserTransaction is used when JTA is required (e.g. to do queries on mulitple things), and that EntityTransaction is used when JPA only is required (e.g. when the query is atomic).
Is that the only difference between the two or is there more to it than that?
My rudimentary understanding is that
UserTransaction is used when JTA is
required (e.g. to do queries on
mulitple things), and that
EntityTransaction is used when JPA
only is required (e.g. when the query
is atomic).
That's basically right, but your description of "multiple things" and "atomic" is a bit strange. JTA allows the developper to use distributed transaction to perform changes on multiples resources (database, JMS broker, etc.) atomically (all-or-nothing). If only one resource is accessed (e.g. one single database), you don't need JTA, but the transaction is still atomic (all-or-nothing). That's for instance the case when you use a regular JDBC transaction on one database.
Considering UserTransaction vs. EntityTransaction:
If JPA is use stand-alone, you use EntityTransaction to demarcate the transaction yourself.
If JPA is used within a managed environment where it integrates with JTA, you use UserTransaction. The EntityManager hooks itself into the JTA distributed transaction manager. The only subtlety I'm aware of considers the flush of the changes. When EntityTransaction is used, JPA know it needs to flush the changes. If transaction are controlled using UserTransaction, it needs to register a callback using JTA registerSynchronization, so that the changes are flushed to the database before the transaction completes. If you use EJB with CMT (container managed transaction), you don't even need to use UserTransaction: the app server starts and stops the transactions for you.
Related questions:
What is difference between UserTransaction and EntityManager.getTransaction() (duplicate)
XA and non-XA datasource with Spring/Hibernate (related)

Categories