I'm calling the following method in service from controller where no @Transnational at the top of method :
@Override
public void test1(Pageable pageable) {
{
Query query =entityManager.createQuery("SELECT U from User U",User.class);
List<User> users=query.getResultList();
User user=new User();
user.setName("hello");
user.setLastName("hello");
entityManager.persist(user);
}
}
I was confused that it worked and the result is committed at the end of method , the entitymanager injected in the service with :
@PersistenceContext
private EntityManager entityManager;
can anybody explains how the transaction is created on method without transnational ?
update: my bad I was using @Transactional on interface without noticing it. but how does the select query work ? when is the session created ? spring.jpa.open-in-view is disabled
Basically, it's possible when using Open Session In View / Open Entity Manager In View patterns.
Spring has Open Entity Manager In View pattern enabled by default (i.e property spring.jpa.open-in-view
is set to true
).
This property tells Spring to register OpenEntityManagerInViewInterceptor
which does the trick.
UPD.
JPA doesn't enforce transactions on read operations. That's why select statement works event without @Transactional
.
If the user doesn't declare transaction boundaries, then each select statement will be executed in a separate transaction (autocommit mode) - that's how JDBC handles this case (i.e JDBC opens a transaction).
JDBC closes transaction immediately after the statement execution and doesn't bind this transaction to any thread.