0

I'm trying to connect my project with db. I have one project that is already connected and operates on this db. And i need second one and communication between them using jms. I configure secon to connect to the same db and it isn`t working. Well connection is ok. When i create Entity class then in db i see new table. So great. But i wrote controller that should inject entity manager and it's always null. i don't have idea why. Here is my config.

@Configuration
@ComponentScan(basePackages = { "**.*****.**********" })
public class CalculationWorkerRootConfig {

    @Bean
    public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocation(new ClassPathResource("/persistence.properties"));
        return ppc;
    }

} 

Here is manager configurer:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
public class CalculationWorkerPersistenceConfig implements TransactionManagementConfigurer {

    @Value("${dataSource.driverClassName}")
    private String driver;
    @Value("${dataSource.url}")
    private String url;
    @Value("${dataSource.username}")
    private String username;
    @Value("${dataSource.password}")
    private String password;
    @Value("${hibernate.dialect}")
    private String dialect;
    @Value("${hibernate.hbm2ddl.auto}")
    private String hbm2ddlAuto;

@Bean
public DataSource configureDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(driver);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    return dataSource;
}

@Bean
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(configureDataSource());
    entityManagerFactoryBean.setPackagesToScan("**.*********.************");
    entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

    Properties jpaProperties = new Properties();
    jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
    jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
    entityManagerFactoryBean.setJpaProperties(jpaProperties);

    return entityManagerFactoryBean;
}

@Bean   
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return new JpaTransactionManager();
}

}

And here is repository:

@Repository
@Transactional(readOnly = true)
public class CalculationWorkerRepository {

@PersistenceContext
EntityManager entityManager; 


public Campaign findByID(Long id) {
    return entityManager.find(Campaign.class, id);
}

@Transactional
public void setCalculating(Boolean calculating, Long campaignID) {
    Campaign campaign = findByID(campaignID);
    campaign.setCalculating(calculating);
}

}
Adrian Deja
  • 737
  • 1
  • 9
  • 17

3 Answers3

9

The class LocalContainerEntityManagerFactoryBean is a factory. You'll notice from the javadoc that it extends AbstractEntityManagerFactoryBean which provides the methods afterPropertiesSet() and getObject(). You need to call these to instantiate an EntityManagerFactory.

@Bean
public EntityManagerFactory configureEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(configureDataSource());
    entityManagerFactoryBean.setPackagesToScan("**.*********.************");
    entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

    Properties jpaProperties = new Properties();
    jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
    jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
    entityManagerFactoryBean.setJpaProperties(jpaProperties);

    entityManagerFactoryBean.afterPropertiesSet();
    return (EntityManagerFactory) entityManagerFactoryBean.getObject();
}

The above will create an EntityManagerFactory. You then need an EntityManager bean.

@Bean
public EntityManager entityManager() {
    return configureEntityManagerFactory.createEntityManager();
}
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

From what I see you are only instantiating an EntityManagerFactory and not an EntityManager, so either you have to inject the EntityManagerFactory or instatntiate an EntityManager at start up that can be injected.

Also note the problems described in this post regarding injection of an EM in relation to transactions and different environments.

Community
  • 1
  • 1
Carsten
  • 1,511
  • 2
  • 13
  • 24
0

The problem is that the JpaTransactionManager is missing a reference to an EntityManagerFactory. Use either constructor injection or setter injection to solve it:

@Bean   
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return new JpaTransactionManager(configureEntityManagerFactory());
}

or

@Bean   
public PlatformTransactionManager annotationDrivenTransactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(configureEntityManagerFactory());
    return transactionManager;
}

Reference, the JpaTransactionManager in the XML application context in the JPA Transaction paragraph in the Spring reference documentation has a corresponding configuration.

matsev
  • 32,104
  • 16
  • 121
  • 156