I'm using Hibernate Validator 4.0.2, Spring 3.0 and Hibernate 3.3.2 (which, as I understand it, is pre-JPA2) as a JPA 1 provider.
I've found it easy to integrate the Validator into the MVC layer (it just works) but can't see how to integrate the validator automatically into the JPA entityManager (JPA 1).
Basically, I have some entities that will be persisted but that do not come from the web layer and have therefore not already been validated. I'd like a neat way of running them through the validator pre-persist.
Is there an easy way of doing this? I'm aware that if I was using a JPA 2 provider (like Hibernate 3.5 when it is released), it'd be almost automatic. That's roughly what I'm looking for.
You need to write an entity listener and to trigger validation on #PrePersist, #PreUpdate and even #PreRemove (there are valid use-case for that). See Bean Validation with JPA 1.0 for a code sample.
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.
I am still a beginner in hibernate.I have started reading the user guide in which i found this architecture.
I know that hibernate is a jpa implementation and the jpa jar contains only interfaces.But i want to understand why JPA API is in the same level as Hibernate native api.
And if JPA contains only Interfaces how can we call for example entityManger.persist(entity) and normaly the entity manager is an interface.
where is the entity manger implementation ???
I know that hibernate is a jpa implementation and the jpa jar contains only interfaces.But i want to understand why JPA API is in the same level as Hibernate native api.
Because you can either use the JPA API (EntityManager, EntityManagerFactory etc) or Hibernate native API (Session, SessionFactory etc) to interact with the ORM entities and the database.
And if JPA contains only Interfaces how can we call for example entityManger.persist(entity) and normaly the entity manager is an interface. where is the entity manger implementation ???
JPA API like EntityManager, EntityManagerFactory etc are implemented by Hibernate (one of the JPA implementations, other like EclipseLink etc do exist). You will find that implementation in one of the hibernate jar files. .
A quick ref of Hibernate implementation of EntityManagerFactory here on grepcode
I get the following exception when I upgrade my app from Hibernate 3.0.5 with Spring 1.0 to Hibernate 4.3.5.Final with Spring 4.0.6.
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1135)
at org.springframework.orm.hibernate4.HibernateTemplate$26.doInHibernate(HibernateTemplate.java:826)
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:340)
at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
at org.springframework.orm.hibernate4.HibernateTemplate.deleteAll(HibernateTemplate.java:823)
...
I have spent several days, done some reasearch, tried different things, and asked the question below:
How can I globally set FlushMode for Hibernate 4.3.5.Final with Spring 4.0.6?
Seems like there are 2 solotions I can go with, but I have still not found the recommended approach.
Approach 1:
Implement a custom version of OpenSessionInViewFilter to set the default FlushMode to AUTO.
Approach 2:
Use a TransactionManager, and add the #Transactional annotation to every method that has write access to the database.
This can be done by following: Spring Hibernate transaction management
Could anyone provide any suggestion, or point out any documentation related to "Starting from version x.x.x, this is how we should implement Hibernate now!"
Thanks a lot
We have an existing j2se project that already uses JPA and guice-persist. Now, because we want to add JMS functionality, there is a request for 2-phase-commit and JTA. We'll use the bitronix transaction manager because there's no container (like spring).
To my understanding, the first thing we have to do is to change the transaction-type of the persistence unit from RESSOURCE-LOCAL to JTA, because we want database transactions to vote for commit rather then commit. The commit is done on phase 2 after collecting all votes.
With guice-persist we use the #Transactional annotation for methods that should run in a single transaction. The JPAPersistModule provides an EnitiyManagerFactory and it is used for guice-persist internal classes, like JpaLocalTxnInterceptor that wraps the annotated methods.
Now I get exceptions like
java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:1009)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:57)
...
because the JpaLocalTxnInterceptor calls getTransaction() on the provided entity manager.
I'm quite stuck, at the moment. Is there any way to use guice-persist together with JTA or o we really have to drop guice-persist from the project? Or, is there any replacement for guice-persist if we want to do JTA (with Bitronix)?
Had a similar situation. In our case we were using Guice + Jooq. We wanted Jooq because we have a large legacy Rails DB and wanted fine control plus speed. We picked Guice over Spring because we felt it is a better framework, and it is much faster and we like compile time checking.
We could NOT use Guice persist with Jooq, so we :
Use Atomikos JTA (free version)
Wrote our own #Transactional AOP annotation interceptor;
Our injectable Service provides the java.sql.Connection to our jooq processors, but always supply an Atomikos DataSource bean
We basically modified this code:
http://www.dailyjavatips.com/2011/10/24/database-transactions-google-guice-aop/
So that example uses regular JDBC Tx, but we modified it so it would use Atmomikos' JTA aware Tx instead.
Works like a charm!
Oje
I'm creating a Java EE application that's using JPA for data access. Initially I used EclipseLink, but the bundled Geronimo Javamail implementation that it depends on via Moxy was giving me some odd issues and I couldn't force it to use Sun Javamail, so I've switched to Hiberate as the JPA provider.
EclipseLink was ignoring the lazy/eager annotations, it was eagerly loading everything. Hibernate pays attention to those annotations, and so dependant objects aren't loaded. That means if I load say a person, with a lazy loading of the persons parents, if I access the parents in the view it's not lazy loaded, I get an exception that says the database session's closed.
I understand there are two ways to get around this:
- Open Session in View pattern/antipattern (which isn't great from a layered point of view, and can have the N+1 database calls problem, but is easy)
- Have service methods that load all the data the view needs (which makes the service layer messy with lots of duplicate methods to get varying amounts of data)
For reference my layers are View -> Controller -> Service -> Entity Object -> JPA. I don't have a dto as it's a small app and I don't like the DTO anti-pattern.
Thinking about the Open Session in View pattern, the problem is the OpenSessionInViewInterceptor and OpenSessionInViewFilter are both Hibernate specific, and both require you to declare a hiberate session on your Spring configuration files. I prefer to stay with pure JPA, configured with a persistence.xml file.
What are my options here? Can I just change my Spring configuration to load Hibernate explicitly, but then use pure JPA inside my application? Is there a pure JPA way achieve the same result, lazy loading from the view?
it sounds odd the EclipseLink ignores standard JPA annotations.
the javamail implementation should not be in any way related to JPA
there is OpenEntityManagerInViewX (filter/interceptor) which handle the same scenario for JPA
you can easily go without this pattern if you declare and use your collections wisely.