package org.javers.spring.example;
import com.google.common.collect.ImmutableMap;
import org.javers.core.Javers;
import org.javers.hibernate.integration.HibernateUnproxyObjectAccessHook;
import org.javers.repository.sql.ConnectionProvider;
import org.javers.repository.sql.DialectName;
import org.javers.repository.sql.JaversSqlRepository;
import org.javers.repository.sql.SqlRepositoryBuilder;
import org.javers.spring.auditable.AuthorProvider;
import org.javers.spring.auditable.CommitPropertiesProvider;
import org.javers.spring.auditable.SpringSecurityAuthorProvider;
import org.javers.spring.auditable.aspect.JaversAuditableAspect;
import org.javers.spring.auditable.aspect.springdata.JaversSpringDataAuditableRepositoryAspect;
import org.javers.spring.jpa.JpaHibernateConnectionProvider;
import org.javers.spring.jpa.TransactionalJaversBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Map;
import java.util.Properties;
/**
* @author bartosz walacik
*/
@Configuration
@ComponentScan(basePackages = "org.javers.spring.repository.jpa")
@EnableTransactionManagement
@EnableAspectJAutoProxy
@EnableJpaRepositories(basePackages = "org.javers.spring.repository.jpa")
public class JaversSpringJpaApplicationConfig {
//.. JaVers setup ..
/**
* Creates JaVers instance with {@link JaversSqlRepository}
*/
@Bean
public Javers javers(PlatformTransactionManager txManager) {
JaversSqlRepository sqlRepository = SqlRepositoryBuilder
.sqlRepository()
.withConnectionProvider(jpaConnectionProvider())
.withDialect(DialectName.H2)
.build();
return TransactionalJaversBuilder
.javers()
.withTxManager(txManager)
.withObjectAccessHook(new HibernateUnproxyObjectAccessHook())
.registerJaversRepository(sqlRepository)
.build();
}
/**
* Enables auto-audit aspect for ordinary repositories.<br/>
*
* Use {@link org.javers.spring.annotation.JaversAuditable}
* to mark data writing methods that you want to audit.
*/
@Bean
public JaversAuditableAspect javersAuditableAspect(Javers javers) {
return new JaversAuditableAspect(javers, authorProvider(), commitPropertiesProvider());
}
/**
* Enables auto-audit aspect for Spring Data repositories. <br/>
*
* Use {@link org.javers.spring.annotation.JaversSpringDataAuditable}
* to annotate CrudRepositories you want to audit.
*/
@Bean
public JaversSpringDataAuditableRepositoryAspect javersSpringDataAuditableAspect(Javers javers) {
return new JaversSpringDataAuditableRepositoryAspect(javers, authorProvider(), commitPropertiesProvider());
}
/**
* Required by auto-audit aspect. <br/><br/>
*
* Creates {@link SpringSecurityAuthorProvider} instance,
* suitable when using Spring Security
*/
@Bean
public AuthorProvider authorProvider() {
return new SpringSecurityAuthorProvider();
}
/**
* Optional for auto-audit aspect. <br/>
* @see CommitPropertiesProvider
*/
@Bean
public CommitPropertiesProvider commitPropertiesProvider() {
return new CommitPropertiesProvider() {
@Override
public Map<String, String> provide() {
return ImmutableMap.of("key", "ok");
}
};
}
/**
* Integrates {@link JaversSqlRepository} with Spring {@link JpaTransactionManager}
*/
@Bean
public ConnectionProvider jpaConnectionProvider() {
return new JpaHibernateConnectionProvider();
}
//.. EOF JaVers setup ..
//.. Spring-JPA-Hibernate setup ..
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("org.javers.spring.model");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
return dataSource;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create");
properties.setProperty("hibernate.connection.autocommit", "false");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return properties;
}
//.. EOF Spring-JPA-Hibernate setup ..
}