SPRING BOOT访问entityManager

时间:2014-10-17 12:29:57

标签: spring hibernate jpa spring-boot

我试图使用springboot更新使用spring和hibernate创建的项目。

一切似乎都没问题,但我无法确定如何获得entityManager。

我没有使用spring数据,因此没有使用域名或存储库。

在这个项目中,服务使用@service注释,而entityManager是autowire:@PersistenceContext,

这是我服务的一个例子

@Service
@Transactional
public class UserServiceImpl implements UserDetailsService, UserService {

@PersistenceContext
EntityManager entityManager;


/**
 * 
 */
private static final long serialVersionUID = 6384460058124202695L;

public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException {
    User user = entityManager.find(User.class, username);
    return user;
}

这里的问题是entityManager为null。所以我在doc中读到,如果我们想管理entityManager,我们必须配置它,所以我在配置文件中这样做了:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPackagesToScan(new String[] { "services" });

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaProperties(additionalProperties());

    return em;
}

应用程序正在启动,但仍然有entityManager null。

有任何线索吗?

编辑:添加我的应用程序类(它是一个演示项目,我将所有配置放在一个文件中)

@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableWebMvcSecurity
public class Application extends WebSecurityConfigurerAdapter{

@Value("${sec.cas.server}")
private String casServer;

@Value("${sec.app.server}")
private String appServer;

@Value("${spring.datasource.driverClassName}")
private String databaseDriverClassName;

@Value("${spring.datasource.url}")
private String databaseUrl;

@Value("${spring.datasource.username}")
private String databaseUsername;

@Value("${spring.datasource.password}")
private String databasePassword;

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(Application.class, args);

    System.out.println("Let's inspect the beans provided by Spring Boot:");

    String[] beanNames = ctx.getBeanDefinitionNames();
    Arrays.sort(beanNames);
    for (String beanName : beanNames) {
        System.out.println(beanName);
    }
}

@Bean
public ComboPooledDataSource dataSource() {
    ComboPooledDataSource datasource = new ComboPooledDataSource();
    try {
        datasource.setDriverClass(databaseDriverClassName);
    } catch (PropertyVetoException e) {
        throw new IllegalArgumentException("Wrong driver class");
    }
    datasource.setJdbcUrl(databaseUrl);
    datasource.setUser(databaseUsername);
    datasource.setPassword(databasePassword);

    datasource.setAcquireIncrement(1);
    datasource.setIdleConnectionTestPeriod(600);
    datasource.setMaxPoolSize(500);
    datasource.setMinPoolSize(50);
    datasource.setMaxStatements(0);

    datasource.setMaxConnectionAge(600);
    datasource.setMaxIdleTime(600);

    return datasource;
}


@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    DefaultPersistenceUnitManager  unitManager = new DefaultPersistenceUnitManager ();
    unitManager.setDefaultDataSource(dataSource());
    unitManager.setPersistenceXmlLocations("classpath*:META-INF/persistence.xml"); //location of     your persistence.xml file
    unitManager.setPackagesToScan(new String[] { "services" });
    unitManager.setDefaultPersistenceUnitName("entityManager");

   LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
   em.setPersistenceUnitManager(unitManager);

   JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
   em.setJpaVendorAdapter(vendorAdapter);
   em.setJpaProperties(additionalProperties());

   return em;
}

Properties additionalProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.show_sql", "false");
    properties.setProperty("hibernate.format_sql", "true");
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle9iDialect");
    return properties;
 }

    @Bean
    public JdbcDaoImpl jdbcUserService() {
        JdbcDaoImpl jdbcDaoImpl = new JdbcDaoImpl();
        jdbcDaoImpl.setEnableGroups(true);
        jdbcDaoImpl.setEnableAuthorities(true);
        jdbcDaoImpl.setDataSource(dataSource());
        return jdbcDaoImpl;
    }

    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService("http://"+appServer+"/j_spring_cas_security_check");
        serviceProperties.setSendRenew(false);
        return serviceProperties;
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
           casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
        casAuthenticationProvider.setUserDetailsService(new UserServiceImpl());
        //casAuthenticationProvider.setAuthenticationUserDetailsService(userServiceImpl.class);
        casAuthenticationProvider.setServiceProperties(serviceProperties());
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
        casAuthenticationProvider.setKey("an_id_for_this_auth_provider_only");
        return casAuthenticationProvider;
    }

    @Bean
    public UserDetailsByNameServiceWrapper authenticationUserDetailsService() {
        UserDetailsByNameServiceWrapper userDetailsByName = new UserDetailsByNameServiceWrapper();
        userDetailsByName.setUserDetailsService(jdbcUserService());
        return userDetailsByName;
    }

    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        Cas20ServiceTicketValidator casServiceTicketValidator = new Cas20ServiceTicketValidator("https://"+casServer+"/cas");
        casServiceTicketValidator.setProxyCallbackUrl("http://"+appServer+"/");
        casServiceTicketValidator.setProxyGrantingTicketStorage(new ProxyGrantingTicketStorageImpl());
        return casServiceTicketValidator;
    }

    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler());
        casAuthenticationFilter.setProxyGrantingTicketStorage(new ProxyGrantingTicketStorageImpl());
        casAuthenticationFilter.setProxyReceptorUrl("/secure/receptor");
        return casAuthenticationFilter;
    }

    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl("https://"+casServer+"/cas/login");
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
        return casAuthenticationEntryPoint;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilter(casAuthenticationFilter());
        http
            .exceptionHandling()
                .authenticationEntryPoint(casAuthenticationEntryPoint());
        http
        .authorizeRequests()
            .antMatchers("/", "/home").authenticated()
            .anyRequest().authenticated();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .authenticationProvider(casAuthenticationProvider());
    }

3 个答案:

答案 0 :(得分:1)

EntityManager null表示Spring并未在@PersistenceContext个实例中处理UserServiceImpl注释。

您在配置UserServiceImpl bean时手动创建CasAuthenticationProvider实例。这意味着Spring对该实例一无所知,也不会注入任何依赖项。您需要使用Spring创建的实例,例如将其作为casAuthenticationProvider()方法的参数。

答案 1 :(得分:0)

尝试:

    DefaultPersistenceUnitManager unitManager = new DefaultPersistenceUnitManager();
    unitManager.setPersistenceXmlLocations("classpath*:META-INF/persistence.xml"); //location of your persistence.xml file.
    unitManager.setDefaultDataSource(dataSource);

在persistence.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

    <persistence-unit name="entityManager" transaction-type="RESOURCE_LOCAL">
        //classes, etc...
    </persistence-unit>

</persistence>

LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitManager(unitManager);
em.setPersistenceUnitName("entityManager");

然后注意:

@PersistenceContext(unitName = "entityManager")
private EntityManager entityManager;

这应该有效。

答案 2 :(得分:0)

OP解决方案。

终于有了工作,不需要重新定义entityManager,只需添加获得@persistenceContext的bean(在spring boot 1.2.0之前)

这是我的申请背景:

@Configuration
@ComponentScan(basePackages={"services","model"})
@EnableAutoConfiguration
public class Application {

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(Application.class, args);
}

@Bean
public PersistenceAnnotationBeanPostProcessor persistenceBeanPostProcessor() {
    return new PersistenceAnnotationBeanPostProcessor();
}