NamedParameterJdbcTemplate in Spring (3.0.5.RELEASE) - spring

I'm trying to use this class but I can't seem to figure out how to limit the rows returned. Plain JdbcTemplate has a max row and max fetch size setter. Is there any way to get similar functionality out of NamedParameterJdbcTemplate ?

NamedParameterJdbcTemplate exposes its underlying JdbcTemplate via NamedParameterJdbcTemplate.getJdbcOperations():
((JdbcTemplate) namedParameterJdbcTemplate.getJdbcOperations()).setMaxRows(...);
Just for information: note that setMaxRows() shouldn't be used to set limits for individual queries (because NamedParameterJdbcTemplate is intended to be thread-safe, so that you shouldn't change its state after it have been initialized). Limits for individual queries are usually set by appropriate SQL clauses.

Related

Intetcept JdbcTemplate without using AOP or wrapper

What all I want to do is automatically collect statistical values from DB for each DML or DQL has been executed in Spring or Spring Boot application.
Take Oracle for example, if I execute a query - select 1 from dual, then I can execute a next query - select * from v$mtstat a, v$statnameb where a.statistic# = b.statistic# to retrieve statistical values for current session.
Therefore, once I use JdbcTemplate or NamedParameterJdbcTemplate to access DB (SELECT/UPDATE/INSERT/DELETE), I also want to collect those statistical values initiatively for further analysis.
I have surveyed several techniques such as datasource-proxy or P6Spy, but they didn't meet my requirement.
So does anyone knows how to achieve this without using AOP or wrapping it?
Any advice and suggestions will be greatly appreciated.

spring jpa, findAll(Iterable<Integer> userIds)

findAll(ListU ..) in spring jpa is called by passing UUID's list of size n, when sql logs are enabled i found n number of sql getting logged ,which i assume DB is being called n times(size of list) to fetch records.
can it be possible to call DB only once to fetch all the records at once so that performance can be improved
Spring Data uses an IN close for this method except when your entity has a composite key. That is already just one query.
So the multiple queries you see is most likely your JPA implementation deciding to return a proxy with just the id and then lazy loading the attributes by demand. See the documentation of the implementation you are using for how to prevent/control that.

Hibernate Envers with QueryDSL Update

Hibernate, Hibernate Envers and QueryDSL are configured and working correctly in a Spring boot 1.4.1.RELEASE.
The problem is when using UpdateClause<JPAUpdateClause> updateQueryBuilder = queryFactory.update(collectionTransaction); to build update query and execute that update query, Hibernate Envers does not pick up and audit those changes.
Following is the Spring Data JPA repository that implements QueryDSL
public class CollectionTransactionRepositoryImpl extends QueryDslRepositorySupport implements CollectionTransactionRepositoryCustom {
#Autowired
private JPAQueryFactory queryFactory;
public CollectionTransactionRepositoryImpl() {
super(CollectionTransaction.class);
}
#Override
public Collection<CollectionTransaction> updateCollectionTransaction(UpdateCollectionTransaction updateCollectionTransaction) {
QCollectionTransaction collectionTransaction = QCollectionTransaction.collectionTransaction;
UpdateClause<JPAUpdateClause> updateQueryBuilder = queryFactory.update(collectionTransaction);
.....//Code omitted for brevity
long updated = updateQueryBuilder.execute();
//.....
return ...
}
}
Is it possible for Hibernate Envers to pick up changes in this situation ?
This is a known concern outlined in JIRA HHH-10318.
Envers works based on Hibernate's event subsystem where Hibernate effectively notifies various callbacks that state for an entity has been modified in some way, and provides both the prior and new entity state. This state is precisely what Envers uses to determine what changed and insert audit change rows.
Lets take a trivial example:
UPDATE MyEntity e SET e.status = :status
Hibernate will perform the following tasks:
Flush the persistence context any any modifications.
Invalidate any cached instances of MyEntity.
Execute the bulk update operation.
No where in any of these steps does Hibernate load any existing state. It simply guarantees that current changes are flushed prior to the bulk update and that any subsequent operations will fetch from the datastore rather than a cache due to the bulk update.
Therefore from Envers perspective, it gets no callbacks and thus isn't aware that any operation took place because Hibernate ORM cannot provide any entity state for such an operation, it simply does not exist.
The big question here is how (if possible) to model and handle a change unit for such an operation.
It's difficult because Envers would effectively need some type of PreBulkOpEvent so that it can cache what it needs that is about to change and a PostBulkOpEvent to require and merge the two results to generate change log entries. The concern with such a concept really centers around how to do this effectively to avoid
Running out of memory due to large result-set manipulation.
Long execution time to load state from datastore for large result-set manipulation.
Anyway, you're welcomed to read over the JIRA and provide any feedback or ideas. But presently, its just something that falls outside the scope of what we can capture at the present moment.

Spring SimpleJdbcInsert vs JdbcTemplate

I have a requirement where I have to insert a row into the Database and get the Key (Identity) back. I thought of using SimpleJdbcInsert for this. I am passing the Object of JdbcTemplate to my SimpleJdbcInsert and executing method executeAndReturnKey().
The same can be done using update() method of JdbcTemplate by setting PreparedStatement instead of Parameters Map.
I just want to know if JdbcTemplate is better in terms of performance and should I be using it over SimpleJdbcInsert? If so then what is the reason for it's superior performance?
Note: I'm not inserting a Batch of Records but a single record only.
Thanks
SimpleJdbcInsert vs JdbcTemplate
From docs.spring.io
JdbcTemplate is the classic Spring JDBC approach and the most popular. This "lowest level" approach and all others use a JdbcTemplate under the covers.
Note :all others use a JdbcTemplate under the covers
SimpleJdbcInsert optimize database metadata to limit the amount of necessary configuration. This approach simplifies coding so that you only need to provide the name of the table or procedure and provide a map of parameters matching the column names. This only works if the database provides adequate metadata. If the database doesn’t provide this metadata, you will have to provide explicit configuration of the parameters.
If you are going to use A SimpleJdbcInsert,then also the actual insert is being handled using JdbcTemplate. So definitely in terms of performance SimpleJdbcInsert can not be better that JdbcTemplate.
So performance wise you can not be beneficial using SimpleJdbcInsert.
But perform insert operations in to multiple tables by using SimpleJdbcInsert is having definitely better capability then JdbcTemplate class.There may be some situation in which you want to insert data in lot of tables and you may like to do less coding.In these situations, using of SimpleJdbcInsert can be a very good option.See this example to understand that.

Is there a generic way of getting columns in ResultsSet of MapRow

I am using SimpleJdbcTemplate and for example I have something like this:
#Override
public Variant mapRow(ResultSet rs, int rowNum) throws SQLException
then I am getting the values from this result set with lines of code like this:
variant.setName(rs.getString("variant_name"));
so I have to look at my table, see what type should I use for each column, - getString for String in this example - ...so I will have getString, getLong, getInt,...
I was wondering if there a more generic way of getting these values from result set without the need to specify the correct type and hope that Spring JDBC takes care of some boxing/unboxing on these generic types
If you want to map JDBC results to your object model, then you're going to have to live with doing that. That's the deal when you use JDBC.
If you want something more high level, including column-to-property mapping, then you need a better tool. You could go the whole hog and use Hibernate, but that carries a whole load of baggage, and presents 10 new problems for every one it solves.
Have a look at MyBatis (formerly known as iBatis). This is a pretty basic framework for mapping JDBC result sets to javabeans, with connection/statement management backed in. Spring provides support for iBatis 2, but iBatis 2 itself is no longer supported. The new MyBatis 3.x isn't supported by Spring out-of-the-box, but the MyBatis project does provide it's own Spring integration.

Resources