加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

带有Spring MVC的JPA通过注释配置

发布时间:2020-12-15 01:40:49 所属栏目:大数据 来源:网络整理
导读:我正在尝试创建一个利用JPA作为其持久层的Spring MVC应用程序.不幸的是,我在访问EntityManager时遇到了NullPointerException,因为Spring似乎没有注入它.我的配置是基于注释的@EnableWebMvc.经过一番搜索,我在我的DAO上添加了@Transactional,在我的@Configura

我正在尝试创建一个利用JPA作为其持久层的Spring MVC应用程序.不幸的是,我在访问EntityManager时遇到了NullPointerException,因为Spring似乎没有注入它.我的配置是基于注释的@EnableWebMvc.经过一番搜索,我在我的DAO上添加了@Transactional,在我的@Configuration类上添加了@EnableTransactionManagement.然后我得到一个关于没有DataSource的错误.据推测,具有@EnableTransactionManagement的类需要实现TransactionManagementConfigurer.但是,我在弄清楚如何创建DataSource以及为什么它无法从我的persistence.xml中获取它时遇到了问题.

我非常感谢任何尝试将EntityManager注入我的DAO的帮助.

我的@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();
}

}

我的DAO

@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

我的更新代码

我已经达到了几乎所有工作的程度. 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;
}

}
最佳答案
在我的应用程序中,我没有实现TransactionManagerConfigurer接口.我使用下一个代码来配置JPA(使用Hibernate实现).您可以在配置类中执行相同的操作.

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean factoryBean = 
                new LocalContainerEntityManagerFactoryBean();

        factoryBean.setDataSource(dataSource());
        factoryBean.setPackagesToScan(new String[] {"com.dimasco.springjpa.domain"});

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        //vendorAdapter.setGenerateDdl(generateDdl)

        factoryBean.setJpaVendorAdapter(vendorAdapter);

        Properties additionalProperties = new Properties();
        additionalProperties.put("hibernate.hbm2ddl.auto","update");

        factoryBean.setJpaProperties(additionalProperties);


        return factoryBean;
    }

    @Bean
    public DataSource dataSource() {
        final ComboPooledDataSource dataSource = new ComboPooledDataSource();

        try {
            dataSource.setDriverClass(driverClass);
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e);
        }

        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setMinPoolSize(3);
        dataSource.setMaxPoolSize(15);
        dataSource.setDebugUnreturnedConnectionStackTraces(true);

        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

希望对你有帮助)

编辑:

您可以使用JNDI查找获取数据源:

@Bean
public DataSource dataSource() throws Exception {
   Context ctx = new InitialContext();
   return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}

更多细节你可以找到in this article.有JndiDatasourceConfig类的例子.

编辑2:
我在我的项目中使用了persistence.xml,但它是空的:

我没有在我的java配置中指定任何持久性单元名称.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读