Question

I'm having problems modifying this basic Spring JPA example to persist changes.

I've modified the example as following:

1) To the Application class, I added

@PropertySource("classpath:application.properties")

and refactored the data access code to be non static:

@Autowired EntityManager em;
@Autowired CustomerRepository repository;
@Autowired DataSource dataSource;
@Autowired EntityManagerFactory emf;
public static void main(String[] args) {
    ConfigurableApplicationContext run = SpringApplication.run(
            Application.class, args);
    Application app = run.getBean(Application.class);
    app.run();
    run.close();
}
public void run(String... args) {
    repository.save(new Customer("Jack", "Bauer"));

2) and put the application.properties in /src/main/resources:

spring.datasource.url: jdbc:h2:./database/bootDB;AUTO_SERVER=TRUE
spring.datasource.driverClassName: org.h2.Driver
spring.jpa.show-sql: true

Now, when I run the program, a bootDB is created, but without a Customer table. If I do change the Application class and add

@Bean
public EntityManagerFactory entityManagerFactory() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("hello");
    factory.setDataSource(dataSource);
    factory.afterPropertiesSet();

    return factory.getObject();
}

everything is fine. Yet, when I debug the previous version, the LocalContainerEntityManagerFactoryBean in the created SimpleJpaRepository for the CustomerRepository seems to be properly configured, since it contains

ConnectionPool[defaultAutoCommit=null; defaultReadOnly=null; defaultTransactionIsolation=-1;(...) url=jdbc:h2:./database/bootDB;AUTO_SERVER=TRUE; username=sa; (...) dataSource=null; dataSourceJNDI=null; (...)

Why doesn't any object gets persisted in the initial setup? Can I fix it in a shorter (or better) manner?

Was it helpful?

Solution

Try adding @Transactional annotation on your method.

Another solution is to create a service that implements InitializingBean. example:

@Service
public class DataPopulator implements InitializingBean  {

@Autowired
private CustomerRepository  repository;

    @Override
    @Transactional()
    public void afterPropertiesSet() throws Exception {
        repository.save(new Customer("Jack", "Bauer"));
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top