Search code examples
javaspring-data-jpaspring-dataguice

How to setup Spring Data JPA with Google Guice


How do I properly setup Guice 4.2.2, Spring-Data-JPA 2.1.4.RELEASE?

I'm currently using org.springframework.guice.spring-guice 1.1.3.RELEASE to configure both projects to work together but I'm having issue when injecting an auto generated CrudRepository.

See my current code:

EmployeeDalConfiguration

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
@GuiceModule(includeFilters = @Filter(type = FilterType.REGEX, pattern=".*\\.Repository"))
public class EmployeeDalConfiguration {
  @Bean
  public DataSource dataSource() {

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL).build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.allierh.webservice.modules.employee.dal.entity");
    factory.setDataSource(dataSource());
    return factory;
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}

EmployeeEntity

@Entity
public class EmployeeEntity {

  @Id
  String id;

  String firstName;

  String lastName;

  public EmployeeEntity() {}
}

EmployeeEntityDao

interface EmployeeEntityDao extends CrudRepository<EmployeeEntity, String> {}

EmployeeDalModule

public class EmployeeDalModule extends AbstractModule {

  @Override
  protected void configure() {
    install(new SpringModule(BeanFactoryProvider.from(EmployeeDalConfiguration.class)));
    bind(EmployeeRepository.class).to(PostgreEmployeeRepository.class);
  }
}

EmployeeRepository

public class EmployeeRepository implements EmployeeRepository {

  private final EmployeeEntityDao dao;

  @Inject
  public EmployeeRepository(EmployeeEntityDao dao) {
    this.dao = dao;
  }
}

With all this, Guice throws an error at runtime saying it can't find an implementation for EmployeeEntityDao. Here's the full stack:

com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for com.foo.webservice.modules.employee.dal.EmployeeEntityDao was bound.
  while locating com.foo.webservice.modules.employee.dal.EmployeeEntityDao
    for the 1st parameter of com.foo.webservice.modules.employee.dal.EmployeeRepository.<init>(EmployeeRepository.java:15)
  at com.foo.webservice.modules.employee.dal.EmployeeDalModule.configure(EmployeeDalModule.java:12) (via modules: com.foo.webservice.modules.employee.api.EmployeeModule -> com.foo.webservice.modules.employee.dal.EmployeeDalModule)

In the end, I simply want to have Guice inject the bootstrapped Spring Data JPA repositories with or without the spring-guice dependency.


Solution

  • Ok I finally figured out a clean and simple way to make this work and without any dependency:

    public class EmployeeDalModule extends AbstractModule {
    
      @Override
      protected void configure() {
        ListableBeanFactory beanFactory = new AnnotationConfigApplicationContext(EmployeeDalConfiguration.class).getBeanFactory();
        bind(EmployeeEntityDao.class).toInstance(beanFactory.getBean(EmployeeEntityDao.class));
        bind(EmployeeRepository.class).to(EmployeeRepositoryImpl.class);
      }
    }
    

    Thanks