Question: From where to start when trying to resolve FactoryBeanNotInitializedException exception while injecting EntityManager into service?
Code:
#Service
public class MyService {
....
#Autowired
private EntityManager entityManager;
Exception:
org.springframework.beans.factory.FactoryBeanNotInitializedException: FactoryBean is not fully initialized yet
try
#PersistenceContext(unitName="puName")
EntityManager em;
and make sure that EntityManager must be registered...
try #PersistenceContext instead of #Autowired
Related
i am searching for a way to create a listener that is also a spring component, however when i try to autowire the entity manager bean, it is always null, what am i doing wrong?
#Component
public class TestListener {
#Autowired
private TestRepository entityManager;
#PrePersist
#PreUpdate
void beforeEntityUpdateOrSave(final Entity entity) {
entityManager.someOperation() // -> NullPointerException, because the bean is "null"
}
}
the Entity class has the listener in the #EntityListeners annotation.
#EntityListeners(TestListener.class)
public class Entity
Is the class TestRepository annotated with #Repository?
You could try making the field entityManager final. I would also recomend using constructor injection instead. Field injection sometimes leads to strange behaviour.
#Component
public class TestListener {
private final TestRepository entityManager;
public TestListener(#Autowired TestRepository entityManager){
this.entityManager = entityManager;
}
...
}
}
#Stateless
public class MyAccountsBean {
#Inject SomeEntityClass someOtherBean;
#Resource UserTransaction jtaTx;
#PersistenceContext(unitName="AccountsPU") EntityManager em;
#Resource QueueConnectionFactory accountsJMSfactory;
#Resource Queue accountPaymentDestinationQueue;
public List<Account> processAccounts(DepartmentId id) {
// Use all of above instance variables with no additional setup.
// They automatically partake in a (server coordinated) JTA transaction
}
}
There are likely multiple issues, but one that sticks out is that all of the fields should be marked with the private modifier.
In addition, can you post the rest of your codebase and the error you are getting?
I have a minimal spring boot application, consisting of 3 classes: an Entity, a component that tries to populate db in #PostConstruct and an application class. Nothing else.
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
#Component
#Transactional
public class Initializer {
#Autowired
EntityManager em;
#PostConstruct
public void populate() {
em.persist(new MyEntity());
}
}
#Entity
public class MyEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
}
When I run the application I get an javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
I'm not the only one ever getting that error and I read a lot of the posts, but did not find a magic solution.
If I autowire an EntityMananagerFactory and instead do:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(new MyEntity());
em.getTransaction().commit();
em.close();
It works. Question is: Is there a simpler way (place the right annotation at the right spot) to get an EntityManager that can persist an entity? I have good reasons for not creating a repository (I tried doing that and that works).
Best regards Jens
So after trying a lot of different stuff, I think that I found a working solution, where the initalization is done in an ApplicationReadyEvent handler instead of in a #PostConstruct method:
#Component
public class Initializer {
#PersistenceContext
EntityManager em;
#EventListener(ApplicationReadyEvent.class)
#Transactional
public void init() {
em.persist(new MyEntity());
}
}
Working example: https://github.com/djarnis73/spring-boot-db-init-with-jpa-entity-manager
As per my understanding, #PostConstruct gets called on app startup when we want to initialize the beans and the configs. I think #PostConstruct is not the right place to do so.
However you can use #PersistenceContext on your entityManger instead of autowiring it.
I'd like for my ResourceConfig to have access to a database for its configuration. I've tried this:
#ApplicationPath("/api")
public class ApplicationConfig extends ResourceConfig {
#PersistenceContext(unitName = "myPU")
private EntityManager em;
#Inject
private MyEjb myEjb;
#PostConstruct
public void init() {
// em and myEjb are both null
...
}
But neither the EntityManager, not the EJB, are injected (both are null)
Is there a special way to do this in JAX-RS?
NOTE: I'm able to inject resources into a Path-annotated class just fine. I'm having trouble doing it in the actual ApplicationPath-annotated class.
Problem:
entityManager.unwrap(SessionImplementor.class) cause no transactional entitymanager available exception.
Code:
#Component
public class HibernateEventWiring {
#Autowired
private ViewListener listener;
#PersistenceContext(unitName = "config-punit")
private EntityManager entityManager;
#PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = getSessionFactory();
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(listener);
}
#Transactional
private SessionFactory getSessionFactory() {
// EXCEPTION: No transactional entitymanager available
return entityManager.unwrap(SessionImplementor.class).getFactory();
}
}
According to this excelent answer:
In the #PostConstruct (as with the afterPropertiesSet from the InitializingBean interface) there is no way to ensure that all the post processing is already done, so (indeed) there can be no Transactions.
As I see, you do not need a transaction nor an entity manager bean, but rather an entity manager factory bean. I think you should simply autowire the EntityManagerFactory and then unwrap the Hibernate SessionFactory from it.
#Autowired
private EntityManagerFactory entityManagerFactory;
#PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
...
}