Hi, this is a crosspost from a question
<https://stackoverflow.com/questions/66663880/jpa-entitymanager-not-working-when-using-guices-privatemodule>
originally asked on Stack Overflow, I thought I might get better results
here. Copying verbatim:
I have a service with a persistence setup using JPA, Hibernate and Guice
(if it's useful, I'm not using Spring). This is the first, *working* version
of my code:
public class BookDao {
@Inject
protected Provider<EntityManager> entityManagerProvider;
protected EntityManager getEntityManager() {
return entityManagerProvider.get();
}
@Transactional
public void persist(Book book) {
getEntityManager().persist(book);
}
}
public class MyAppModule extends AbstractModule {
@Override
protected void configure() {
initializePersistence();
}
private void initializePersistence() {
final JpaPersistModule jpaPersistModule = new
JpaPersistModule("prod");
jpaPersistModule.properties(new Properties());
jpaPersistModule.configure(binder());
install(jpaPersistModule);
}
}
But now I need to configure multiple persistence units. I'm following the
advice in this mailing list
<https://groups.google.com/g/google-guice/c/2VK-bdsnjZc/discussion>, and
according to them, I should move my module logic to a private module. I did
as suggested and created a second version of the same code, the changes are
commented below:
@BindingAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ FIELD, PARAMETER, METHOD })
public @interface ProductionDataSource {} // defined this new annotation
public class BookDao {
@Inject
@ProductionDataSource // added the annotation here
protected Provider<EntityManager> entityManagerProvider;
protected EntityManager getEntityManager() {
return entityManagerProvider.get();
}
@Transactional
public void persist(Book book) throws Exception {
getEntityManager().persist(book);
}
}
public class MyAppModule extends PrivateModule { // module is now
private
@Override
protected void configure() {
initializePersistence();
// expose the annotated entity manager
Provider<EntityManager> entityManagerProvider =
binder().getProvider(EntityManager.class);
bind(EntityManager.class).annotatedWith(ProductionDataSource.class).toProvider(entityManagerProvider);
expose(EntityManager.class).annotatedWith(ProductionDataSource.class);
}
private void initializePersistence() {
JpaPersistModule jpaPersistModule = new
JpaPersistModule("prod");
jpaPersistModule.properties(new Properties());
install(jpaPersistModule);
}
}
The newly annotated EntityManager is being correctly injected by Guice and
is non-null, but here's the fun part: some of my unit tests started
failing, for example:
class BookDaoTest {
private Injector injector;
private BookDao testee;
@BeforeEach
public void setup() {
injector = Guice.createInjector(new MyAppModule());
injector.injectMembers(this);
testee = injector.getInstance(BookDao.class);
}
@Test
public void testPersistBook() throws Exception {
// given
Book newBook = new Book();
assertNull(newBook.getId());
// when
newBook = testee.persist(newBook);
// then
assertNotNull(newBook.getId()); // works in the first version,
fails in the second
}
}
In the first version of my code the last line above just *works*: the
entity is persisted and has a new id. However, in the second version of my
code (using a PrivateModule and exposing an annotated EntityManager from
it) the persist() operation doesn't work anymore, the entity is without an
id. What could be the problem? I didn't do any other configuration changes
in my environment, and I don't see error messages in the logs. Let me know
if you need more details.
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/google-guice/128c00ca-9bb3-42c5-ace4-79973ccb3f13n%40googlegroups.com.