Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
DataSource Configuration
Disable Spring Data JPA’s auto-configuration classes
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class,
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration.class
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class
})
Below is the entire manual JPA configuration
import org.hibernate.SessionFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;
@Configuration
public class MySqlConfig {
@Bean
public UserRepository userRepository() throws IOException {
DataSource dataSource = DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/first_database?createDatabaseIfNotExist=true")
.username("root")
.password("")
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource);
localSessionFactoryBean.setPackagesToScan("com.example.demo");
localSessionFactoryBean.setHibernateProperties(hibernateProperties());
// initialize bean
localSessionFactoryBean.afterPropertiesSet();
SessionFactory sessionFactory = localSessionFactoryBean.getObject();
EntityManager em = sessionFactory.createEntityManager();
// Create your transaction manager and RepositoryFactory
// final HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
final JpaTransactionManager transactionManager = new JpaTransactionManager(sessionFactory);
final JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
// Make sure calls to the repository instance are intercepted for annotated transactions
factory.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
factory.addAdvice(new TransactionInterceptor(transactionManager, new MatchAlwaysTransactionAttributeSource()));
}
});
// Create your repository proxy instance
UserRepository userRepository = factory.getRepository(UserRepository.class);
// Bind the same EntityManger used to create the Repository to the thread
TransactionSynchronizationManager.bindResource(sessionFactory, new EntityManagerHolder(em));
return userRepository;
}
private Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create");
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
hibernateProperties.setProperty("hibernate.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
return hibernateProperties;
}
}
Since we are using a MySQL driver in this example, you must add that driver to the classpath
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.31</version>
</dependency>
Create Entities
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Data
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
}
Create Repositories
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
Customer findById(long id);
}
Using Repositories
@Autowired
private CustomerRepository customerRepository;
Customer customer = customerRepository.save(new Customer());
System.out.println("Customer auto-generated id = " + customer.getId());