我想創建一個Spring JPA應用程序,利用它的持久層JPA。不幸的是,當訪問EntityManager時,我得到了一個NullPointerException,因爲Spring似乎沒有注入它。我的配置是基於@EnableWebMvc的所有註釋。經過一番搜索之後,我在我的@Configuration類中添加了@Transactional對我的DAO和@EnableTransactionManagement。然後我得到一個關於沒有DataSource的錯誤。據推測,具有@EnableTransactionManagement的類需要實現TransactionManagementConfigurer。但是,我在解決如何創建DataSource時遇到問題,以及爲什麼無法從我的persistence.xml中獲取它。JPA與Spring MVC通過註釋配置
我非常感謝任何幫助,試圖讓我的DAO注入EntityManager。
我@Configuration類
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.example.myapp")
public class MvcConfig extends WebMvcConfigurerAdapter
implements TransactionManagementConfigurer {
private static final boolean CACHE_ENABLED = true;
private static final String TEMPLATE_PATH = "/WEB-INF/freemarker";
private static final String TEMPLATE_SUFFIX = ".ftl";
private static final Logger LOG = Logger.getLogger(MvcConfig.class);
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/stylesheets/**").addResourceLocations("/stylesheets/");
}
@Bean
public FreeMarkerConfigurer configureFreeMarker() {
final FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath(TEMPLATE_PATH);
return configurer;
}
@Bean
public ViewResolver configureViewResolver() {
final FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
resolver.setCache(CACHE_ENABLED);
resolver.setSuffix(TEMPLATE_SUFFIX);
return resolver;
}
@Bean
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager();
}
}
吾道
@Component
@Transactional
public class MyDAO {
private static final Logger LOG = Logger.getLogger(MyDAO.class);
@PersistenceContext
private EntityManager entityManager;
public MyClass getMyClass() {
LOG.debug("getMyClass()");
final CriteriaQuery<MyClass> query = criteriaBuilder.createQuery(MyClass.class);
// more code here, but it breaks by this point
return myData;
}
}
我更新的代碼
我已經達到了點,其中幾乎所有的作品。 EntityManager正在被正確注入。但是,交易不起作用。如果我嘗試使用RESOURCE_LOCAL方法,則會收到錯誤,因此我正在查看JTA託管事務。當我在任何一個DAO方法中添加@Transactional時,我會得到一個「標記爲回退的事務」錯誤,在任何日誌文件中都沒有進一步的詳細信息來幫助進行故障排除。如果我從一個基本的只讀選擇中刪除註釋,選擇將工作得很好(不知道我是否應該將註釋放在只選方法上)。不過,我顯然需要這種處理db寫入的方法。如果我通過代碼調試,它似乎很好地檢索數據。但是,從方法返回時,將引發javax.transaction.RollbackException。從我對所有事物的理解中,似乎AOP後處理方法中發生異常。
我@Configuration類
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.example.myapp")
public class MvcConfig extends WebMvcConfigurerAdapter {
private static final boolean CACHE_ENABLED = true;
private static final String TEMPLATE_PATH = "/WEB-INF/freemarker";
private static final String TEMPLATE_SUFFIX = ".ftl";
private static final Logger LOG = Logger.getLogger(MvcConfig.class);
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/stylesheets/**").addResourceLocations("/stylesheets/");
}
@Bean
public FreeMarkerConfigurer configureFreeMarker() {
final FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath(TEMPLATE_PATH);
return configurer;
}
@Bean
public ViewResolver configureViewResolver() {
final FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
resolver.setCache(CACHE_ENABLED);
resolver.setSuffix(TEMPLATE_SUFFIX);
return resolver;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager();
}
@Bean
public AbstractEntityManagerFactoryBean entityManagerFactoryBean() {
LocalEntityManagerFactoryBean factory = new LocalEntityManagerFactoryBean();
factory.setPersistenceUnitName("my_db");
return factory;
}
}
這輕微地關心我,你顯式引用Hibernate特定的類,因爲它似乎將它綁定到底層實現。 此外,理想情況下,我會使用JNDI查找數據源,但不熟悉如何做。我假設這不是這樣做的? – Marshmellow1328 2013-02-10 18:57:27
關於綁定到底層實現 - 即使您在沒有Spring的情況下使用JPA,也可以在persistence.xml中定義持久性提供程序設置。在這裏你可以在一個方法entityManagerFactoryBean()中的代碼中定義它們。但你可以將它們移動到XML配置文件) – dimas 2013-02-10 19:06:08
我添加了示例如何在我的原始答案中通過JNDI查找來獲取DataSource。 – dimas 2013-02-10 19:13:27