I am writing a java application in which I am using Spring Boot and JPA in order to map classes to my database tables.
However, due to a somewhat complex database structure I also have the need of creating custom queries that are not mapped to any specific POJOs / Entities.
Therefore I am using PreparedStatement together with a DataSource with #Autowired annotation.
It hit me that using both of these DB Access methods might not be suitable to use together?
So far everything has worked out in my dev environment, but are there any pitfalls that I should look out for when using both of these together or is there a preferred way of doing custom queries when using JPA?
It should be noted that my database calls are fairly short and happen in a stateless manner, so there should hopefully not be any problems with interfering sessions (?)
JPA EntityManager will not know anything about your changes made with PreparedStatement. This will cause issues with JPA built-in caching, maybe with versioning and also with transaction support.
Though you may need to check this question: Is it OK to use both JPA (for normal CRUDs) and JDBC (for batch update & call stored proc) in the same project
Invan's answer makes a clear point.
On the other hand your fine when:
you need complex queries to SHOW data (read only).
you infrequently need to do some batch updates and do a clear cache entityManager.getEntityManagerFactory().getCache().evictAll()
Related
I am creating a webapp in Spring Boot (Spring + Hibernate + MySQL).
I have already created all the CRUD operations for the data of my app, and now I need to process the data and create reports.
As per the complexity of these reports, I will create some summary or pre proccesed tables. This way, I can trigger the reports creation once, and then get them efficiently.
My doubt is if I should build all the reports in Java or in Stored Procedures in MySQL.
Pros of doing it in Java:
More logging
More control of the structures (entities, maps, list, etc)
Catching exceptions
If I change my db engine (it would not happen, but never know)
Cons of doing it in Java:
Maybe memory?
Any thoughts on this?
Thanks!
Java. Though both are possible. It depends on what is most important and what skills are available for maintenance and the price of maintaining. Stored procedures are usually very fast, but availability and performance also depends on what exact database you use. You will need special skills, and then you have it all working on that specific database.
Hibernate does come with a special dialect written for every database to get the best performance out of the persistence layer. It’s not that fast as a stored procedure, but it comes pretty close. With Spring Data on top of that, all difficulty is gone. Maintenance will not cost that much and people who know Spring Data are more available than any special database vendor.
You can still create various “difficult” queries easily with HQL, so no block there. But Hibernate comes with more possibilities. You can have your caching done by eh-cache and with Hibernate envers you will have your audit done in no time. That’s the nice thing about this framework. It’s widely used and many free to use maven dependencies are there for the taking. And if in future you want to change your database, you can do it by changing like 3 parameters in your application.properties file when using Spring Data.
You can play with some annotations and see what performs better. For example you have the #Inheritance annotation where you can have some classes end up in the same table or split it to more tables. Also you have the #MappedSuperclass where you can have one JpaObject with the id which all your entities can extend. If you want some more tricks on JPA, maybe check this post with my answer on how to use a superclass and a general repository.
As per the complexity of these reports, I will create some summary or
pre proccesed tables. This way, I can trigger the reports creation
once, and then get them efficiently.
My first thought is, is this required? It seems like adding complexity to the application that perhaps isn't needed. Premature optimisation and all that. Try writing the reports in SQL and running an execution plan. If it's good enough, you have less code to maintain and no added batch jobs to administer. Consider load testing using E.G. jmeter or gatling to see how it holds up under stress.
Consider using querydsl or jooq for reporting. Both provide a database abstraction layer and fluent API for querying databases, which deliver the benefits listed in the "Pros of doing it in Java" section of the question and may be more suited to the problem. This blog post jOOQ vs. Hibernate: When to Choose Which is well worth a read.
Note: This is not a programming question (at least at the moment). Once I start progressing further would seek assistance from the community on programming questions. Feel free to delete this, if this question is deemed inappropriate.
I am trying to start using DashDB as a Database on Bluemix. The DashDB data would be consumed by a Java/Java EE app
I am not planning to use this as a Data warehouse.
DashDB as I understand it has two flavours - Regular (using this term loosely here to refer to the standard offering ) and DashDB Transactional.
DashDB Transaction, i believe is used for transactional workloads.
I wanted to understand if JPA would play well with DashDB. I am unable to locate good information in this space.
Should we use denormalized design for both DashDB Regular and Transactional?
The dashDB Transactional Bluemix plan provides a dashDB database that is optimized for online transaction processing (OLTP). This means that it is designed for highly structured repetitive processing and it supports ACID transactions. That said you should use all the best practices you would use with a classic RDBMS: normalization, constraints and so on. I confirm that the dashDB-JPA integration is not well documented yet, but there should be no particular problem in using it with JPA. Since your application will run on Liberty Runtime, when you bind the dashDB service instance the server.xml is automatically configured with dataSource with a JNDI name and the database driver jars are also added.
JPA does not work seamlessly with DashDB today. DashDB uses organized by column be default and JPA does not work well with it. There is no specific way today to set organize by row using an annotation in JPA. We tried to override the DB2Dictionary but that did not work either.
If i drop the table using sql statement and recreate the table using sql statement appended with organize by row, then JPA is able to read the table.
Not sure who should be fixing this issue - JPA or DashDB :)
what we are planning to do is we want a single project but want to use three different frame works to-gather, so is it a good idea or can this is achievable ?
we have already project build up with spring and hibernate but we want to extend it with jdbc template.
please guide on common quetions like
-New Session factory required or not ?
-Can we use pojos with hibernate annotations with jdbc template or we have to create new one ?
-Will this create problem on performance if average is 500 users at a time ?
Thanks in advance.
Using both an ORM and JDBC in the same application is a reasonable thing to do. Hibernate can run native SQL queries so you might consider that as an alternative depending on what you have in mind.
JDBC doesn't use a session factory or entity manager factory comparable to Hibernate. Caching for the JDBC results would have to be handled separately from Hibernate.
The Hibernate/JPA annotations will be irrelevant to JDBC queries, the RowMapper passed into the query controls how pojos get populated. You could re-use your Hibernate entities to be populated by the rowmappers but in practice the reason you use JDBC is to get more focused results with flatter objects and you end up with a separate set of DTOs.
I'm not clear on what you think is going to hurt performance here. JDBC should be an improvement over Hibernate performance-wise, though at the cost of having business-logic spread out in multiple places. The tricky part will probably be setting up the transaction manager so that JDBC and Hibernate use the same transaction, see this question.
I have been trying to use Hibernate for a while. I like hibernate that it has annotation mapping ability (such as #Entity, #Column)
But I don't like it caching idea ( How to disable hibernate caching said that it also cannot be disabled).
Also, I totally don't like its 'commits vs flush' idea which not directly run SQL to database when do insert/delete/update some data in database.
So, as my title, are there any frameworks like Hibernate with annotation but no cache and do directly execute SQL? It would be good if such frameworks can use in Spring.
Or, actually, Can Hibernate just disable cache or just have some configuration that can do direct SQL for every insert/delete/update?
These features are on by default, because you usually need them (even though you don't realize initially).
But if you really want to disable cache and flush everything immediately:
use sessionFactory.openStatelessSession() - this session does not store anything in the 1st level cache (and the 2nd level cache is off by default). Note that you can't operate collection mappings with this session.
use session.setFlushMode(..) to set it to flush automatically before very query (rather discouraged).
Note that the flush mode is available only for stateful sessions - the stateless session is flushed immediately.
Hibernate is a great framework, but for more lightweight implementations I tend to use Spring JDBC:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html
You might be looking for MyBatis, which is a bit more direct. For an annotation-based example, see here although there are others. You can also just use pure JDBC, or via Spring if you're using Spring.
I don't understand the "not liking caching" thing.
Just trying to get my head round Spring and figuring out how I wire up an Oracle connection in xml config file, and now find out I need yet another framework! - Hibernate, this is soooo frustrating as it feels like I'm getting deeper and deeper into more and more frameworks without actually getting what I need done!
I looked at Hibernate and it seems to do similar things to Spring, bearing in mind I just want to do some SQL inserts in Oracle.
I am reluctant and do not have time to learn 2 frameworks - could I get away with just adopting Hibernate for the simple things I need to do?
...could I get away with just adopting Hibernate for the simple things I need to do?
Yes
Hibernate is for ORM ( object relational mapping ) that is, make your objects persistent to a RDBMS.
Spring goes further. It may be used also as a AOP, Dependency Injector, a Web Application and ORM among other things.
So if you only need ORM, just use Hibernate. Time will come when you need Spring, and you will learn it then.
Here's an architectural view of Spring:
And this is Hibernate:
Spring and Hibernate are totally different frameworks for different problems. Spring is a huge framework with many many features, Hibernate is an O/R bridge.
I would recommend using plain old JDBC in your case ('just some SQL inserts in Oracle').
You could get away with using just spring and spring-JDBC integration. Depending on the complexity of your data-access needs it may be more than enough. The spring Object-relation mapping is also worth looking into if you're going to do a lot of data-access.
The nice thing about spring is that it's a very loosely coupled framework. So you can read up on the bits you use, and forget the rest - even in the runtime.
Spring and Hibernate are really intended to do two different things. Spring is first and foremost an inversion-of-control container and configuration subsystem, while Hibernate is a database binding and lazy loading engine. If you don't want to introduce a bunch of new stuff into your code, stick with Spring and roll your own queries or use iBatis to do much simpler database binding.
If all you want is insert sql for oracle I would stick to a simple JDBC library. All you need is a Connection and maybe some ConnectionPool (maybe c3po). Hibernate and the like are too big/too complicated and IMO inferior. Hibernate incorporates JDBC under the hood but in every measurable way is inferior -- harder to use, not faster, and the queries you have to write or not any easier. It is also a testament to their inferiority because HQL also provides a bypass route so you can enter JDBC queries directly. They provide this (I suspect) because for any complex query you simply can't construct it well in HQL.