This is how I configure JPA in Spring.
... <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"> </bean> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3306/test"> </property> <property name="username" value="root"> </property> <property name="password" value="root"> </property> </bean> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> <property name="jpaVendorAdapter" ref="jpaVendorAdapter"> </property> <property name="dataSource" ref="dataSource"> </property> <property name="packagesToScan" value="org.huahsin"> </property> </bean> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="jpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect"> </property> <property name="showSql" value="true"> </property> </bean>The primary object in this configuration was the LocalContainerEntityManagerFactoryBean. According to the documentation, this is the most powerful way to set up a shared JPA EntityManagerFactory in Spring application context. I take 3 parameters in this configuration:
- dataSource - the bean that establish connection to database.
- jpaVendorAdapter - optional parameters in persistence.xml.
- packagesToScan - the packages where the entities is reside.
@Repository public class UserDao implements IUserDao { @PersistenceUnit private EntityManagerFactory emf; public User findByUsername(String username) { List<user> l = null; try { l = (List<user>) emf.createEntityManager().createQuery("from User").getResultList(); // verify on the list of users for( User u : l ) { System.out.println(u.getUsername()); } return null; // simply return NULL for testing purpose } finally { emf.close(); } } }The second option is to obtain an instance of EntityManager through @PersistenceContext injection.
@Repository public class UserDao implements IUserDao { @PersistenceContext private EntityManager em; public User findByUsername(String username) { List<User> l = null; try { l = (List<User>) em.createQuery("from User").getResultList(); // verify on the list of users for( User u : l ) { System.out.println(u.getUsername()); } return null; // simply return NULL for testing purpose } finally { emf.close(); } } }Do not mess up with the injection. If I accidentally do this on EntityManagerFactory like this:
@PersistenceContext
private EntityManagerFactory emf;
This error would be seen when the bean is trigger during run-time:
Caused by: java.lang.IllegalStateException: Specified field type [interface javax.persistence.EntityManagerFactory] is incompatible with resource type [javax.persistence.EntityManager] at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.checkResourceType(InjectionMetadata.java:134) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.<init>(PersistenceAnnotationBeanPostProcessor.java:620) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:381) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:322) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:830) ... 27 moreSame to EntityManager, if I mistakenly do this:
@PersistenceUnit
private EntityManager em;
This will be the result during the run-time:
Caused by: java.lang.IllegalStateException: Specified field type [interface javax.persistence.EntityManager] is incompatible with resource type [javax.persistence.EntityManagerFactory] at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.checkResourceType(InjectionMetadata.java:134) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.There is a nice comment on this error why this shouldn't be done appear on this question in stackoverflow.com. The user claim that(PersistenceAnnotationBeanPostProcessor.java:620) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:381) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:322) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:830) ... 27 more
An entity manager can only be injected in classes running inside a transaction. In other words, it can only be injected in a EJB. Other classe must use an EntityManagerFactory to create and destroy an EntityManager. - Andre Rodrigues
No comments:
Post a Comment