javaguiceguice-persist

Injecting EntityManager with Guice


after I received a very good answer in my post about Guice injection in general, I wanted to know, if you could also help me with injection of EntityManagers in Guice.

I already read the article https://github.com/google/guice/wiki/JPA about Guice JPA. My code looks like this (I need the providers for my work):

Provider:

public class DatabaseControllerProvider implements Provider<DatabaseControllerInterface> {


    private final Provider<EntityManager> entityManagerProvider;

    @Inject
    public DatabaseControllerProvider(final Provider<EntityManager> manager) {
        this.entityManagerProvider = manager;
    }

    @Override
    public DatabaseControllerInterface get() {
        return new DatabaseControllerImpl(entityManagerProvider.get());
    }
}

Constructor of DatabaseControllerImplementation:

public class DatabaseControllerImpl implements DatabaseControllerInterface {

    private final EntityManager em;

    @Inject
    public DatabaseControllerImpl(final EntityManager manager) {
        this.em = manager;
    }
}

Top level I call this:

public LogInFront() {
        final Injector injector = Guice.createInjector(new ModuleBinder(), new JpaPersistModule("ATVPersistence"));
        final PersistService persistService = persistenceInjector.getInstance(PersistService.class);
        persistService.start();
        logInService = injector.getInstance(LogInServiceInterface.class);
}

to instantiate the JPAPersistService with my database.

I receive an error, that no Implementation for EntityManager was bound, but if I call

...
public LogInFront() {
        final Injector injector = Guice.createInjector(new JpaPersistModule("ATVPersistence"));
        final PersistService persistService = persistenceInjector.getInstance(PersistService.class);
        persistService.start();
        logInService = injector.getInstance(LogInServiceInterface.class);
}

The instantiation works correctly, database works fine, and everything is nice and easy.

So my guess is, that there's something wrong with my GuiceModule. As seen above, when I'm not calling the new ModuleBinder(), everything works just fine.

public class ModuleBinder extends AbstractModule {
    @Override
    protected void configure() {
        bind(DatabaseControllerInterface.class).asEagerSingleton();
        bind(AnalyzerInterface.class).asEagerSingleton();
        bind(SystemAdministrationInterface.class).asEagerSingleton();
        bind(LogInServiceInterface.class).asEagerSingleton();
    }
}

-----------------------------EDIT-------------------------------------

Rewrote above section.

Tl;dr edition: ModuleBinder messes up Injection of EntityManager -why?

---------------------------Found error-------------------------------

I feel kind of dumb, I found the error. When taking a look into the ModuleBinder you can see, that it binds everything as EagerSingleton, but obviously, the EntityManager does not exist yet (the PersistService is started after creating the Injector). I created a new post on this here: https://stackoverflow.com/questions/47181835/jpapersistencemodule-guice-injector

May it help other people!

Best regards,

JosefRucksack


Solution

  • I feel kind of dumb, I found the error. When taking a look into the ModuleBinder you can see, that it binds everything as EagerSingleton, but obviously, the EntityManager does not exist yet (the PersistService is started after creating the Injector).

    Calling

    final Injector injector = persistenceInjector.createChildInjector(new ModuleBinder());
    

    Fixes everything. It creates a childInjector that knows everything the parent knows, therefore the PersistenceService is already started and you can inject the EntityManager into everything.