awfun
awfun

Reputation: 2488

Spring Data - data is loaded but not persisted

I'm trying to use Spring Data for the first time. I've created my repository interface for Spring to implement. I use findAll() method, and it works well. However, save() and delete() methods don't work as I expect: no data is persisted, though no exception is thrown.

I tried to debug through Hibernate code, and I see event EntityDeleteAction[com.my.test.City#2] is added to the ActionQueue, but its execute() method is not called. And I did not manage to find out why.

Could you help me please? Below is database creation code, java config, my entity and repository code:

CREATE TABLE cities(
  id SERIAL PRIMARY KEY,
  name VARCHAR(45) NOT NULL UNIQUE
);
INSERT INTO cities(id, name) VALUES (1, 'Moscow');
INSERT INTO cities(id, name) VALUES (2, 'St.Petersburg');

City.java

@Entity
@Table(name = "cities")
public class City {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;
    public String name;
}

CityRepository.java:

@Repository
public interface CityRepository extends CrudRepository<City, Long> {}

AppConfig.java (part)

@EnableWebMvc
@Configuration
@ComponentScan(value = ...)
@EnableJpaRepositories("com.my.test.repository")
@Import(value = {
        SecurityConfig.class,
        WebMvcConfig.class
})
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
public class AppConfig extends WebSecurityConfigurerAdapter

@Bean
DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getProperty("db.driver"));
    dataSource.setUrl(env.getProperty("db.url"));
    dataSource.setUsername(env.getProperty("db.username"));
    dataSource.setPassword(env.getProperty("db.password"));
    return dataSource;
}

@Bean
SessionFactory sessionFactory() {
    LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource());
    sessionBuilder.scanPackages("com.my.test");
    sessionBuilder.addProperties(getHibernateProperties());
    return sessionBuilder.buildSessionFactory();
}

@Bean
PlatformTransactionManager transactionManager() {
    return new HibernateTransactionManager(sessionFactory());
}

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPackagesToScan(
            "com.my.test.repository",
            "com.my.test.entity"
    );
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    return em;
}

private Properties getHibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
    properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
    return properties;
}

Method I execute:

cityRepository.delete(2);

Thank you for help!

Upvotes: 1

Views: 83

Answers (1)

awfun
awfun

Reputation: 2488

As M. Deinum wrote, the issue was in incorrect transaction manager. This was the solution:

delete bean sessionFactory()

replace beans:

@Bean
public JpaTransactionManager transactionManager() {
    return new JpaTransactionManager(entityManagerFactory().getObject());
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
    em.setPackagesToScan(
            "com.my.test.repository",
            "com.my.test.entity"
    );
    em.setJpaProperties(getHibernateProperties());
    return em;
}

Upvotes: 1

Related Questions