Scott Marlow wrote:
Can you switch to using @PersistenceContext EntityManager or @PersistenceUnit EntityManagerFactory?
If you insist on doing it the hard way, you could possibly get some ideas of how to configure the persistence unit by looking at the AS JPA container implemention code. Currently, you can look at the integration module for Hibernate here https://github.com/wildfly/wildfly/blob/master/jpa/hibernate4/src/main/java/org/jboss/as/jpa/hibernate4/HibernatePersistenceProviderAdaptor.java and https://github.com/wildfly/wildfly/blob/master/jpa/hibernate4/src/main/java/org/jboss/as/jpa/hibernate4.
This example code will show you some additional properties that you can pass in and probably should (The AS JPA EE container automatically adds the additional properties for container managed persistence contexts).
Scott
I can't use @PersistenceContext because I have to use many database. I changed my method getProperties() based on yours info.
Now it looks like :
@Singleton
@Startup
public class CompanyEntityManagerFactory {
@EJB
private CoreCompanyFacade companyFacade;
private Map<Long, EntityManagerFactory> entityManagers = new HashMap();
private final static String PERSISTANCE_UNIT = "PU_SYSTEM";
@PostConstruct
public void initializeEntityManagers() {
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
for (CoreCompany company : getCompanies()) {
entityManagers.put(company.getId(), getEntityManagerFactoryForCompany(company));
initializeEntityManager(company.getId());
}
}
private void initializeEntityManager(Long companyId) {
getEntityManagerForCompany(companyId).createNativeQuery("select now()").getSingleResult();
}
public EntityManager getEntityManagerForCompany(Long companyId) {
return entityManagers.get(companyId).createEntityManager();
}
private EntityManagerFactory getEntityManagerFactoryForCompany(CoreCompany company) {
Properties properties = getProperties(company.getDatabaseConnection());
return Persistence.createEntityManagerFactory(PERSISTANCE_UNIT, properties);
}
private Properties getProperties(CoreCompanyDatabaseConnection databaseConnection) {
Properties properties = new Properties();
properties.put("javax.persistence.provider", "org.hibernate.ejb.HibernatePersistence");
properties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
properties.put("javax.persistence.jdbc.user", databaseConnection.getUser());
properties.put("javax.persistence.jdbc.password", databaseConnection.getPassword());
properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
properties.put("javax.persistence.jdbc.url", databaseConnection.getJdbcUrl());
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
properties.put(Configuration.USE_NEW_ID_GENERATOR_MAPPINGS, "true");
properties.put(org.hibernate.ejb.AvailableSettings.SCANNER, HibernateAnnotationScanner.class.getName());
properties.put(AvailableSettings.JTA_PLATFORM, "org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform");
properties.remove(AvailableSettings.TRANSACTION_MANAGER_STRATEGY); // remove legacy way of specifying TX manager (conflicts with JTA_PLATFORM)
properties.put(org.hibernate.ejb.AvailableSettings.ENTITY_MANAGER_FACTORY_NAME, PERSISTANCE_UNIT);
properties.put(AvailableSettings.SESSION_FACTORY_NAME, PERSISTANCE_UNIT);
return properties;
}
private List<CoreCompany> getCompanies() {
return companyFacade.getCompaniesWithDatabaseConnection();
}
But in HibernatePersistenceProviderAdaptor.java is JBossAppServerJtaPlatform injecting by method void injectJtaManager(JtaManager jtaManager).
I think that this could be problem. Question is how I can inject this in my class?
Now I chenged update method to:
private void mergeWithCustomTransaction(T entity) {
getEntityManager().merge(entity);
getEntityManager().flush();
}
And with all changes only select queries are ok. During update I have exception:
17:14:56,655 ERROR [stderr] (http--127.0.0.1-8080-1) javax.persistence.TransactionRequiredException: no transaction is in progress
17:14:56,657 ERROR [stderr] (http--127.0.0.1-8080-1) at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:970)
Also after few minutes on jboss console I notice :
16:59:08,242 WARN [org.hibernate.internal.SessionFactoryImpl] (MSC service thread 1-1) HHH000008: JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()
16:59:17,350 INFO [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (MSC service thread 1-1) HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
16:59:17,351 INFO [org.hibernate.engine.transaction.internal.TransactionFactoryInitiator] (MSC service thread 1-1) HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
16:59:17,353 INFO [org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory] (MSC service thread 1-1) HHH000397: Using ASTQueryTranslatorFactory
17:03:53,878 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffff7f000101:54c164c7:51827f06:8 in state RUN
17:03:53,881 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012095: Abort of action id 0:ffff7f000101:54c164c7:51827f06:8 invoked while multiple threads active within it.
17:03:53,884 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012108: CheckedAction::check - atomic action 0:ffff7f000101:54c164c7:51827f06:8 aborting with 1 threads active!
17:03:53,912 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012121: TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,main] successfully canceled TX 0:ffff7f000101:54c164c7:51827f06:8
I restart jboss and made the same operations and this message didn't show again....