我想创建一个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