Reputation: 417
I have a simple Spring Boot application with the following auto-configuration properties:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mywebapp
spring.datasource.username=username
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=validate
These work fine and I'm able to setup Spring Data JpaRepositories:
public interface UserRepository extends JpaRepository<User, String>
{
User findByName(String name);
}
...for the following entities:
@Entity
public class User
{
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String email;
}
...and use them like this:
@Transactional
public void updatePassword(String username, String password)
{
User user = userRepository.findByName(username);
user.setEmail("[email protected]"); // This gets persisted automatically by the JpaRepository.
}
Now I'm struggling to configure the same thing manually. I've tried the following:
@Configuration
@EnableTransactionManagement
public class PersistenceConfig
{
@Bean
public DataSource dataSource()
{
DataSource dataSource = new DataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/mywebapp");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan("com.example.persistent");
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "validate");
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
@Bean
public HibernateTransactionManager transactionManager()
{
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
...but while no exceptions are thrown and i can now successfully read from the database, it seems that none of the changes I make to the entities are being persisted.
Does anyone have an idea what I'm missing for the persistence to work?
Upvotes: 3
Views: 2374
Reputation: 417
OP here.
I seem to have misunderstood that JPA needs an EntityManager instead of a session.
The following configuration works:
@Configuration
@EnableTransactionManagement
public class PersistenceJpaConfig
{
@Bean
public DataSource dataSource()
{
DataSource dataSource = new DataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/mywebapp");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.example.persistent");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.setProperty("hibernate.hbm2ddl.auto", "validate");
em.setJpaProperties(properties);
return em;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf)
{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
{
return new PersistenceExceptionTranslationPostProcessor();
}
}
Upvotes: 2