Spring jpa: Do I need to add #Transactional annotation on retrieval queries - spring

I am using EntityManger for the retrieval queries in my spring boot application. An example snippet is given below.
#Repository
public class EntityManagerUtil {
#PersistenceContext
private EntityManager entityManager;
public List<Employee> getAll(){
// Use entityManager here
}
}
I need some clarity on the below questions.
a. Is EntityManger will be created for every call (or) will it be a singleton? (I tried printing entityManager, it is returning the same object for all the calls)
b. Is this approach leads to any connection leaks?
c. Do I need to put #Transactional annotation on reading operations?
I am using spring boot version 2.0.3-release

a) See M Deinum's comments about the injected EntityManager being a proxy. The normal situation for JPA is to have an EntityManager tied to each thread, Spring sets this up for you and provides a proxy to delegate to the actual EntityManager. So this arrangement is safe.
b) Connection leaks happen when you don't return a database connection to the pool. Spring takes care of providing a connection and cleaning up resources so in the normal course of things you shouldn't get connection leaks. If you ignore the facilities Spring gives you like JdbcTemplate and insist on writing your own JDBC code, then you can cause resources to leak. If your code tries to use an EntityManager intended for another thread you will get an exception, it will not fail silently, and it will not (in itself) cause a connection leak.
c) You are using an RDBMS so you will have a transaction.
Apparently some people think transactions are optional, but they really aren't. If you don't specify them then Spring will wrap each operation in its own transaction. Not only are you just better off in general being explicit about this, but you can mark the transaction as readonly, which lets Spring perform some optimizations, see Oliver Drotbohm's answer for details. So maybe you can get by without it for some cases (such as, each http request results in only one database operation), but it is in your interest to use it.

Related

What is better to use with JPA FetchType.LAZY #Transactional or #NamedEntityGraph

I used Spring Boots #Transactional on the Service Layer to avoid the Lazyinitializationexception. But is there an advantage of using #NamedEntityGraph instead of #Transactional to avoid Lazyinitializationexception?
#NamedEntityGraph not only avoid Lazyinitializationexception but also helps optimizing the number of requests sent to avoid N+1 effect. This may be a valuable advantage but needs more work to ensure that every needed object will be fetched before the end of the hibernate session.

#Transactional with 1 save statement

Does it make sense mark with spring's #Transactional a method with a single save sentence?
For example:
// does it make sense mark it with #Transactional if it only has 1 save sentence?
#Transactional
public void saveMethod() {
user.save()
}
If you´re using Spring data interface, you dont need use #transactional annotation. Only in case that you want to provide two execution against the database and you want to share the transaction, so then rollback of both actions can be made.
Anyway it is always better use #transactional even as read-only for get queries(setting the FlushMode to MANUAL to let persistence providers potentially skip dirty checks when closing the EntityManager), so I would suggest put the #transactional as Service layer and read-only for get queries.
Yes because any "modifications" on the database requires a transaction (to commit the changes). You might think otherwise because of auto-commit, but in the end, there is still a transaction there somewhere.
But it is always a good thing to explicitly define the boundaries of your transaction (when transaction is started and when it is committed).

Inject Session object to DAO bean instead of Session Factory?

In our application we are using Spring and Hibernate.
In all the DAO classes we have SessionFactory auto wired and each of the DAO methods are calling getCurrentSession() method.
Question I have is why not we inject Session object instead of SessionFactory object in prototype scope? This will save us the call to getCurrentSession.
I think the first method is correct but looking for concrete scenarios where second method will throw errors or may be have bad performance?
When you define a bean as prototype scope a new instance is created for each place it needs to be injected into. So each DAO will get a different instance of Session, but all invocations of methods on the DAO will end up using the same session. Since session is not thread safe it should not be shared across multiple threads this will be an issue.
For most situations the session should be transaction scope, i.e., a new session is opened when the transaction starts and then is closed automatically once the transaction finishes. In a few cases it might have to be extended to request scope.
If you want to avoid using SessionFactory.currentSession - then you will need to define your own scope implementation to achieve that.
This is something that is already implemented for JPA using proxies. In case of JPA EntityManager is injected instead of EntityManagerFactory. Instead of #Autowired there is a new #PersistenceContext annotation. A proxy is created and injected during initialization. When any method is invoked the proxy will get hold of the actual EntityManager implementation (using something similar to SessionFactory.getCurrentSession) and delegate to it.
Similar thing can be implemented for Hibernate as well, but the additional complexity is not worth it. It is much simpler to define a getSession method in a BaseDAO which internally call SessionFactory.getCurrentSession(). With this the code using the session is identical to injecting session.
Injecting prototype sessions means that each one of your DAO objects will, by definition, get it's own Session... On the other hand SessionFactory gives you power to open and share sessions at will.
In fact getCurrentSession will not open a new Session on every call... Instead, it will reuse sessions binded to the current session context (e.g., Thread, JTA Transacion or Externally Managed context).
So let's think about it; assume that in your business layer there is a operation that needs to read and update several database tables (which means interacting, directly or indirectly, with several DAOs)... Pretty common scenario right? Customarily when this kind of operation fails you will want to rollback everything that happened in the current operation right? So, for this "particular" case, what kind of strategy seems appropriate?
Spanning several sessions, each one managing their own kind of objects and bound to different transactions.
Have a single session managing the objects related to this operation... Demarcate the transactions according to your business needs.
In brief, sharing sessions and demarcating transactions effectively will not only improve your application performance, it is part of the functionality of your application.
I would deeply recommend you to read Chapter 2 and Chapter 13 of the Hibernate Core Reference Manual to better understand the roles that SessionFactory, Session and Transaction plays within the framework. It will also teach will about Units of work as well as popular session patterns and anti-patterns.

Grails service transactional behaviour

In a Grails app, the default behaviour of service methods is that they are transactional and the transaction is automatically rolled-back if an unchecked exception is thrown. However, in Groovy one is not forced to handle (or rethrow) checked exceptions, so there's a risk that if a service method throws a checked exception, the transaction will not be rolled back. On account of this, it seems advisable to annotate every Grails service class
#Transactional(rollbackFor = Throwable.class)
class MyService {
void writeSomething() {
}
}
Assume I have other methods in MyService, one of which only reads the DB, and the other doesn't touch the DB, are the following annotations correct?
#Transactional(readOnly = true)
void readSomething() {}
// Maybe this should be propagation = Propagation.NOT_SUPPORTED instead?
#Transactional(propagation = Propagation.SUPPORTS)
void dontReadOrWrite() {}
In order to answer this question, I guess you'll need to know what my intention is:
If an exception is thrown from any method and there's a transaction in progress, it will be rolled back. For example, if writeSomething() calls dontReadOrWrite(), and an exception is thrown from the latter, the transaction started by the former will be rolled back. I'm assuming that the rollbackFor class-level attribute is inherited by individual methods unless they explicitly override it.
If there's no transaction in progress, one will not be started for methods like dontReadOrWrite
If no transaction is in progress when readSomething() is called, a read-only transaction will be started. If a read-write transaction is in progress, it will participate in this transaction.
Your code is right as far as it goes: you do want to use the Spring #Transactional annotation on individual methods in your service class to get the granularity you're looking for, you're right that you want SUPPORTS for dontReadOrWrite (NOT_SUPPORTED will suspend an existing transaction, which won't buy you anything based on what you've described and will require your software to spend cycles, so there's pain for no gain), and you're right that you want the default propagation behavior (REQUIRED) for readSomething.
But an important thing to keep in mind with Spring transactional behavior is that Spring implements transaction management by wrapping your class in a proxy that does the appropriate transaction setup, invokes your method, and then does the appropriate transaction tear-down when control returns. And (crucially), this transaction-management code is only invoked when you call the method on the proxy, which doesn't happen if writeSomething() directly calls dontReadOrWrite() as in your first bullet.
If you need different transactional behavior on a method that's called by another method, you've got two choices that I know of if you want to keep using Spring's #Transactional annotations for transaction management:
Move the method being called by the other into a different service class, which will be accessed from your original service class via the Spring proxy.
Leave the method where it is. Declare a member variable in your service class to be of the same type as your service class's interface and make it #Autowired, which will give you a reference to your service class's Spring proxy object. Then when you want to invoke your method with the different transactional behavior, do it on that member variable rather than directly, and the Spring transaction code will fire as you want it to.
Approach #1 is great if the two methods really aren't related anyway, because it solves your problem without confusing whoever ends up maintaining your code, and there's no way to accidentally forget to invoke the transaction-enabled method.
Approach #2 is usually the better option, assuming that your methods are all in the same service for a reason and that you wouldn't really want to split them out. But it's confusing to a maintainer who doesn't understand this wrinkle of Spring transactions, and you have to remember to invoke it that way in each place you call it, so there's a price to it. I'm usually willing to pay that price to not splinter my service classes unnaturally, but as always, it'll depend on your situation.
I think that what you're looking for is more granular transaction management, and using the #Transactional annotation is the right direction for that. That said, there is a Grails Transaction Handling Plugin that can give you the behavior that you're looking for. The caveat is that you will need to wrap your service method calls in a DomainClass.withTransaction closure and supply the non-standard behavior that you're looking for as a parameter map to the withTransaction() method.
As a note, on the backend this is doing exactly what you're talking about above by using the #Transactional annotation to change the behavior of the transaction at runtime. The plugin documentation is excellent, so I don't think you'll find yourself without sufficient guidance.
Hope this is what you're looking for.

Which method in BMP is used to avoid unnecessary round trips to the database?

If I'm using BMP bean, is there any method which avoids unnecessary roundtrips to database and increase the efficiency...
Does any of these method serve the purpose? (Question in a certification test)
ejbSave(), ejbStore() or ejbPersist()
In a multi-tiered architecture, with database, application server, and Web layers—you optimize performance by reducing the network traffic “round trip.” Best approach is said to be to start and stop transactions at the application server level, in the EJB container. So would like to know the methods help reduce unnecessary round-trips for that in Bean Managed persistence type beans....Am new to ejb.., so am trying to learn the concepts
ejbSave() and ejbpersist() do not exist...
You wouldn't have to deal with any of these methods: 'ejbSave(), ejbStore() or ejbPersist()'
If I'm using BMP bean, is there any method which avoids unnecessary roundtrips to database
Short Answer:
Yes, methods of EntityManager
Long Answer:
To avoid network round trips to the database, you'd just have to set the transaction boundaries correctly. When you use the methods provided by EntityManager (I'm talking about JPA), the methods act on the persistence context. The persistence context being a cache, real db hits are avoided until the commit happens.
Following is a section from the TomEE docs
JPA 101
If there's one thing you have to understand to successfully use JPA (Java
Persistence API) it's the concept of a Cache. Almost everything boils
down to the Cache at one point or another. Unfortunately the Cache is an
internal thing and not exposed via the JPA API classes, so it not easy to
touch or feel from a coding perspective.
Here's a quick cheat sheet of the JPA world:
A Cache is a copy of data, copy meaning pulled from but living
outside the database.
Flushing a Cache is the act of putting modified data back into the
database.
A PersistenceContext is essentially a Cache. It also tends to have
it's own non-shared database connection.
An EntityManager represents a PersistenceContext (and therefore a
Cache)
An EntityManagerFactory creates an EntityManager (and therefore a
PersistenceContext/Cache)
With you are
responsible for EntityManager (PersistenceContext/Cache) creating and
tracking...
-- You must use the EntityManagerFactory to get an EntityManager
-- The resulting EntityManager instance is a
PersistenceContext/Cache
-- An EntityManagerFactory can be injected via the #PersistenceUnit
annotation only (not #PersistenceContext)
-- You are not allowed to use #PersistenceContext to refer to a unit
of type RESOURCE_LOCAL
-- You must use the EntityTransaction API to begin/commit around
every call to your EntityManger
-- Calling entityManagerFactory.createEntityManager() twice results in
two separate EntityManager instances and therefor two separate
PersistenceContexts/Caches.
-- It is almost never a good idea to have more than one instance of
an EntityManager in use (don't create a second one unless you've destroyed
the first)
With the container
will do EntityManager (PersistenceContext/Cache) creating and tracking...
-- You cannot use the EntityManagerFactory to get an EntityManager
-- You can only get an EntityManager supplied by the container
-- An EntityManager can be injected via the #PersistenceContext
annotation only (not #PersistenceUnit)
-- You are not allowed to use #PersistenceUnit to refer to a unit of
type TRANSACTION
-- The EntityManager given by the container is a reference to the
PersistenceContext/Cache associated with a JTA Transaction.
-- If no JTA transaction is in progress, the EntityManager cannot be
used because there is no PersistenceContext/Cache.
-- Everyone with an EntityManager reference to the same unit in the
same transaction will automatically have a reference to the same
PersistenceContext/Cache
-- The PersistenceContext/Cache is flushed and cleared at JTA
commit time
Cache == PersistenceContext
The concept of a database cache is an extremely important concept to be
aware of. Without a copy of the data in memory (i.e. a cache) when you
call account.getBalance() the persistence provider would have to go read
the value from the database. Calling account.getBalance() several times
would cause several trips to the database. This would obviously be a big
waste of resources. The other side of having a cache is that when you call
account.setBalance(5000) it also doesn't hit the database (usually). When
the cache is "flushed" the data in it is sent to the database via as many
SQL updates, inserts and deletes as are required. That is the basics of
java persistence of any kind all wrapped in a nutshell. If you can
understand that, you're good to go in nearly any persistence technology
java has to offer.
Complications can arise when there is more than one
PersistenceContext/Cache relating the same data in the same transaction.
In any given transaction you want exactly one PersistenceContext/Cache for
a given set of data. Using a TRANSACTION unit with an EntityManager
created by the container will always guarantee that this is the case. With
a RESOURCE_LOCAL unit and an EntityManagerFactory you should create and use
exactly one EntityManager instance in your transaction to ensure there is
only one active PersistenceContext/Cache for the given set of data active
against the current transaction.

Resources