I use Hibernate with Spring and initialize it with LocalContainerEntityManagerFactoryBean bean with hibernate.show_sql=false in JpaProperties of it. So, I disabled SQL output of Hibernate, but I want to print SQL only for some Query, that I want to debug.
Is it possible to set hibernate.show_sql for Query programmatically, to don't print all SQL queries at runtime, but print them only for some Query?
And no, it's not a duplicate. Because, everything, that explained in suggested answer is already done in my app. I need to enable SQL logging not for all Queries in my app, but only for one Query.
Related
I have plain JDBC code which is doing transaction management using Connection Interface. I wanted to switch to Spring Transaction Management in small steps.
Firstly I want to provide PlatformTransactionManager for my datasource and annotate my class / methods with #Transaction and keep my other logic same ie. using connection / PreparedStatement etc.
All the examples, which I see use JdbcTemplate. I was wondering can Spring Transaction be used without JdbcTemplate?
Technically it is possible to use #Transactional without JdbcTemplate . But if you try to do it , you will sooner or later find that you are re-inventing what the things that are already done by JdbcTemplate.
What #Transactional does is that before executing a #Transactional method , it will help you to get a JDBC Connection from the DataSource , and start a transaction on this Connection .The JDBC Connection will then stored in a ThreadLocal.
That means if you do it without JdbcTemplate , you have to manually get this Connection from that ThreadLocal such that you can create a JDBC Statement from it for executing your SQL. Not to mention you have to manually release the JDBC resources such Statement , ResultSet etc. properly by yourself which all of these things are already take care by JdbcTemplate.
But if you have already implemented these JDBC codes manually and just want to let #Transactional to handle the transaction , you could try to inject the DataSource to your bean and then use the following method to get the Connection for your JDBC codes use :
Connection connection = DataSourceUtils.getConnection(dataSource);
Also checkout JdbcTemplate#execute(ConnectionCallback<T> action) , it is useful for migrating the existing JDBC codes that expects a JDBC Connection to work on to JdbcTemplate.
Yes it's possible. Adding a #Transactional annotation to your methods, as long as they follow the correct procedure should make your methods transactional. But as others have mentioned if you're in the process of updating your app you might as well ditch plain JDBC and move across to Spring JPA/JDBC (depending on which version of Spring you're using).
Thanks for looking at this. I have a tomcat spring boot application using JPA/Hibernate with mysql database back end. There are REST controllers exposed and various service methods are annotated with "#Transactional".
There are entity and repo objects used by JPA/Hibernate to persist and query data from the mysql database. The SQL queries are generated by JPA Hibernate entity and repo objects, like as follows:
public interface FooRepo extends JpaRepository < Foo, String > {
}
The above means that there is a table Foo which has a primary key of type String. There is also a separate class Foo.
While using the above FooRepo to query a single row in the table I see the following SQL queries
set session transaction read
select * from Foo where id='IdToQuery';
set session transaction read write
I understand the select SQL statement but not able to understand why "set session transaction read" is being executed?
Thanks,
ash
After Googling, the only suggestion that I found was to implement a separate read-only transaction connection pool.
From: http://256stuff.com/gray/docs/misc/performance_optimizing_spring_hibernate_transactions/
I have a simple Web MVC application using Spring Boot that communicates with a database; the DB is H2 and has been in memory until now. I want to change that, and thus use a jdbc:h2:file:... URL.
Up until now, I have not needed to add any XML to configure my application, and I'd prefer it to stay that way if possible. But I can't figure out how to specify a different JDBC URL. I obtained and inspected the data source by passing it to an #Bean method:
org.apache.tomcat.jdbc.pool.DataSource#745e6f01{ConnectionPool[
defaultAutoCommit=null;
defaultReadOnly=null;
defaultTransactionIsolation=-1;
defaultCatalog=null;
driverClassName=org.h2.Driver;
maxActive=100;
maxIdle=100;
minIdle=10;
initialSize=10;
maxWait=30000;
testOnBorrow=false;
testOnReturn=false;
timeBetweenEvictionRunsMillis=5000;
numTestsPerEvictionRun=0;
minEvictableIdleTimeMillis=60000;
testWhileIdle=false;
testOnConnect=false;
password=********;
url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;
username=sa;
validationQuery=null;
validationQueryTimeout=-1;
validatorClassName=null;
validationInterval=30000;
accessToUnderlyingConnectionAllowed=true;
removeAbandoned=false;
removeAbandonedTimeout=60;
logAbandoned=false;
connectionProperties=null;
initSQL=null;
jdbcInterceptors=null;
jmxEnabled=true;
fairQueue=true;
useEquals=true;
abandonWhenPercentageFull=0;
maxAge=0;
useLock=false;
dataSource=null;
dataSourceJNDI=null;
suspectTimeout=0;
alternateUsernameAllowed=false;
commitOnReturn=false;
rollbackOnReturn=false;
useDisposableConnectionFacade=true;
logValidationErrors=false;
propagateInterruptState=false;
ignoreExceptionOnPreLoad=false;
}
(newlines mine)
The setup of that bean seems rather intricate, so I want to interfere with it as little as possible - just replace the default JDBC URL.
How can I configure individual properties for Spring to create the datasource? Preferably in Java, but if there is a concise XML way I'm happy as well. I just want to avoid adding 100 lines of boilerplate for something equivalent to url=...
A DataSource is auto configured by Spring Boot for you. To influence how and what there are several properties you can set. Those are prefixed with spring.datasource, for a list take a look at the Spring Boot Reference Guide for a full list.
In your case simply add the following to the application.properties file
spring.datasource.url=jdbc:h2:file:...
This will tell Spring Boot to use this URL instead of the default.
As H2 is considered an in-memory database and not a regular database, when using JPA this will lead to your database to be dropped when the application is stopped. To fix this simply add the following
spring.jpa.hibernate.ddl-auto=update
To specify a dialect simply add the following
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
or even simpler
spring.jpa.database=H2
I understand that Hibernate uses transparent write behind by default for committing the transactions.
However, I would like my entity-manager to commit my transaction on the database immediately after the transaction is committed. Is there anyway I can configure this in persistence.xml of JPA ?
Hibernate would have to commit in the database at the time is made commits the transaction. You can also find it helpful to have two additional options:
Define the Session and autocommit (entering the property "hibernate.connection.autocommit" in the properties of the connection)
Forcing hibernate transaction synchronize with the database transaction in the middle of the transaction (by session.flush ())
Regards,
I am currently using version 3.3 of hibernate.
Currently the setting of hibernate is such that it will autocommit after each persistence of individual object.
I want to wrap a transaction around it, so it will only commit after end of a batch.
The code is in question:
getHibernateTemplate().saveOrUpdateAll(collectionOfObject);
I have consulted the documentation here, but want to see if there is alternative (other than rewriting it to use HSQL)
EDIT
My goal is to have a transaction around a bunch of insert. Currently it is auto-commit per insert
If you want to use transaction management in Spring read here on how to do it.
Also, Use should not be using HibernateTemplate use the Session object instead as below.
sessionFactory = getHibernateTemplate().getSessionFactory();
Session session = sessionFactory.getCurrentSession();
for (Bean bean : listBeans) {
session.saveOrUpdate(bean );
}
As there is no way to save the collection at one shot in session. This will commit the data after method exit.