When creating Wicket apps (or any web apps), one of the first things you usually want to do is interact with your database. There’s many different ways to do this, but here we will look at one approach that will get you going in 10 minutes with very little code.
In this example we will be using:
- MySQL as our database
- Hibernate as our ORM
- HikariCP for connection pooling
- Spring Data JPA for our data access layer (repositories) and transaction management
Add a Configuration class
The first step is to create a “Spring-Boot” style configuration class which will take care of setting up the database connection, pooling, and transaction management:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackageClasses = DaoPackage.class)
public class AppConfig {
private static String[] packagesToScan = new String[] {BaseEntity.class.getPackageName()};
@Primary
@Bean
public DataSource dataSource() {
HikariConfig cfg = new HikariConfig();
cfg.setJdbcUrl(Utils.getVariable("JDBC_CONNECTION_STRING"));
cfg.setDriverClassName("com.mysql.cj.jdbc.Driver");
return new HikariDataSource(cfg);
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan(packagesToScan);
return entityManagerFactoryBean;
}
@Primary
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
There are several things to note above:
- You don’t need to call or execute AppConfig yourself. Because it’s annotated with @Configuration, Spring will automatically create the three beans defined in the class.
- packagesToScan on line 5 is referring to the package where your Hibernate entity classes will be.
- On line 11,
JDBC_CONNECTION_STRING
is the name of the environment variable where you will pass your connection string. - The @EnableJpaRepositories annotation will enable the data repositories that we discuss in the next section. It needs to know the package name where the repositories are defined to configure them.
Add your Hibernate entities and Repository
The next and last step is to create our Hibernate entities corresponding to our database tables and their associated repositories. A Spring repository is just a class that contains methods for querying a specific Hibernate entity.
I will assume we know how to create Hibernate entities, so what about repositories? Using Spring data creating them is very simple:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
That’s it! This interface will now allow us to query Users and because we extend JpaRepository, we get plenty of convenience methods included. Let’s look at how we could use it inside of our Wicket pages:
@SpringBean private UserRepository userRepository;
...
List<User> allUsers = userRepository.findAll();
Optional<User> u = userRepository.findById(15);
We can add custom queries into our repository as well:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
@Query("SELECT u FROM User u where u.email = :email")
Optional<User> findByEmail(@Param("email") String email);
}
Conclusion
From experience, this is one of the quickest ways, with the least amount of code, to create your data access layer. I’m curious how it can be simplified further.
If you have any trouble setting this up, refer to the full working source code on GitHub.