I have a Spring/Roo application which uses PostgreSQL and Hibernate.
As is appropriate, the connection information is located in the database properties file
src/main/resources/META-INF/spring/database.properties
Unfortunately, I have a situation where querying the database through Hibernate is draining the resources too much. I am sure that I can extract the database information (url/username/password) from the file listed above, but I am not sure where to begin my search.
Is there a manual or otherwise where I can find this information?
If you wish to bypass Hibernate to write more efficient queries by hand, you don't have to make separate connections to do it, and should not do so.
Get a Hibernate session and unwrap it to get the underlying java.sql.Connection. Or use native SQL via Hibernate's own interfaces.
That way you still get to use the useful bits of Hibernate, like the connection pooling integration. Sharing the same connection pool as Hibernate will improve efficiency, and you'll have a lot less extra code if you do it this way.
I haven't used Spring Roo, so I can't speak specifically for it. Here's info for Hibernate used via JPA or here. For direct Hibernate usage where you have a Session object, use Session.connection() on old versions of Hibernate, or the Work interface on newer versions:
Session.doWork()
session.connection() deprecated on Hibernate?
How to get jdbc connection from hibernate session?
Alternative of deprecated hibernate getSession().connection()
If you insist on doing this by hand anyway, start with ClassLoader.getResource(...).
Related
I know that Spring Data JPA uses Hibernate, however, I have some questions that need clarification.
Will I be able to use other Hibernate features such as C3P0, Hibernate second level caching, or Hibernate sessions if I use Spring Data JPA?
What are the advantages of using #Query for writing custom queries over using hibernate sessions and HQL?
Is there any performance difference between using Spring Data JpaRepository query methods and using Hibernate HQL?
I have seen the other similar questions here and they don't answer these questions.
I know that Spring Data JPA uses Hibernate
No. It uses JPA. Even though Hibernate is the default JPA implementation of Spring Boot, and the most popular JPA implementation, any JPA engine can be used.
Will I be able to use other Hibernate features such as C3P0
C3P0 has nothing to do with Hibernate. It's a connection pool. You can use any connection pool you wnt both with Spring and with Hibernate. Spring Boot uses HikariCP by default, and I would stick to that (it's a very good pool).
Hibernate second level caching
Yes.
or Hibernate sessions if I use Spring Data JPA?
There's really no good reason to use the old, proprietary Hibernate Session API, instead of using the standard JPA API. If you really need to, I don't see why you couldn't use it, but I wouldn't (and never had to).
What are the advantages of using #Query for writing custom queries over using hibernate sessions and HQL?
Query takes a HQL (JPQL, to be exact) query. If you use Query, you use HQL. The advantage is that you just need to declare the query. the binding of parameters, execution of the query, paging, etc. are done for you by Spring. But you can use custom repository implementations and use the native JPA API if you need to.
Is there any performance difference between using Spring Data JpaRepository query methods and using Hibernate HQL?
No.
Is it possible to use hibernate-search only for it's annotations (bean => document/document => bean mapping), without using a database at all? If so, are there any online samples that show basically how to set this up?
I found the following: http://mojodna.net/2006/10/02/searchable-annotation-driven-indexing-and-searching-with-lucene.html, but I'd prefer hibernate-search if it supports my use case.
Hibernate search 3.4 has decoupled the query engine from Hibernate Core. For instance, Hibernate Search is reused to implement queries with Infinispan. I don't know if the code is packaged so that you could use HS with, let's say Spring and JDBCTemplate (something I would like to do). That's a lead I will investigate later but maybe you can check it out...
Starman is correct, Hibernate Search in version 3.4 is abstracting the search engine from Hibernate Core, and the Infinispan Query is an integration example which works fine without a database. There would be no problems with Spring either, but you'd need to make sure to send update event to the query engine so that the index doesn't get out of synch. When using Hibernate the advantage is that it transparently listens for changes to the database and applies them to the index at transaction commit, so the index is always in synch (or close, if configuring Search to use async backends).
I'd suggest to look into the code of Infinispan Query, as it's very small and just delegating calls to expose an Infinispan flavoured API. Most of the code is tests or integration to properly manage the lifecycle of the engine: start and stop it together with Infinispan.
I don't think that's possible because when you enable Hibernate search you are enabling that on a Entity and that Entity has references to the table and the search index.
I just downloaded Hibernate 4.2.3 Final and see that it has several optional libraries, though I'm not sure what it uses them for or under what circumstances they are needed/desired:
jboss-logging-3.1.0.GA.jar - is this a native SLF4J binding? Is there a way to have Hibernate not use this for logging, and instead use SLF4J and a different binding? If so, how?
C3P0 and Proxool JARs are also optionally included; are these the only two connection pool frameworks that Hibernate can be configured to use? What if I wanted to use, day, BoneCP? What if I wanted to let JNDI (Tomcat/DBCP) decide what connection pool to use?
What is hibernate-entitymanager?
What is hibernate-envers?
Hibernate now uses jboss-logging, refer to: How do you configure logging in Hibernate 4 to use SLF4J
I never heard of others, I'm sure they are good for most of use cases. If you want to use Tomcat/DBCP you can use as a JTA datasource. I don't think there is a connection provider for hibernate 3 or 4. Source: http://wiki.apache.org/commons/DBCP/Hibernate
If you want to use the HibernateEntityManager instead the javax.persistence.EntityManager, you can have the jar on your classpath and code with it.
Envers is an "automagical" auditing/versioning extension, where you annotate the Entities with #Audited and during the transaction, the changes would be also persisted. There is more here http://www.jboss.org/envers.
Earlier I was trying to get batch inserts working in Hibernate. I tried everything: For the config I set batch_size(50), order_inserts(true), order_updates(true), use_second_level_cache(false), use_query_cache(false). For the session I used setCacheMode(CacheMode.IGNORE) and setFlushMode(FlushMode.MANUAL). Still the MySQL query log showed that each insert was coming in separately.
The ONLY thing that worked was setting rewriteBatchedStatements=true in the JBDC connection string. This worries me, as my application is supposed to support any JBDC database and I'm trying to avoid DB specific optimizations.
Is the only reason hibernate can't actually use batch statements because the MySQL driver doesn't support them by default? What about other drivers, do I have to add options to the connection string so they can support batched inserts? If you need specific db's, think SQL server, sqlite, Postgres, etc
One reason it could not be working is that hibernate disables batching if you use the Identity id generation strategy.
Also MySQL doesn't support JDBC batch prepared statements the same way as other databases without turning on the rewrite option.
I don't see that it is a problem to turn this flag on though, if your are setting up your application for a different database you will have to change the settings such as dialect, driver name, etc. anyway and as this is part of the JDBC connect String then you are isolated from the configuration.
Basically I think you are doing the right thing.
As batch insert (or bulk insert) is part of the SQL standard, ORM frameworks like Hibernate support and implement it. Please see Chapter 13. Batch Processing and Hibernate / MySQL Bulk insert problem .
Basically, you need to set the JDBC batch size via the variable named hibernate.jdbc.batch_size to a reasonable size. Also don't forget to end the batch transaction with flush() and clear().
We are migrating a JDBC based application to JPA and EJB3. Our old application used the Connect#setClientInfo API to record the current user name as part of the client info:
http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html#setClientInfo%28java.lang.String,%20java.lang.String%29
We need to do something similar in the EJB3 project. How?
We can use EJB3 interceptors around the EJB service calls in order to capture the current user and set it as info on the datasource. However, I see problems with this. I think there is no guarantee when the JPA flush() occurs. If you set the client info in an interceptor, make some updates, and then return, the flush() and actual database write may not occur until well after your bean (and interceptor) are out of scope. Is this correct?
I believe JPA and EntityManagers are abstractions over the connection, and you cannot reliable set the client info on the connection. True or false?
What JPA provider are you using?
EclipseLink has support for user based connection, Oracle proxy connections and VPD. EclipseLink also defines Session and connection level events that allow you to set configuration on the JDBC connection.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing