Я чувствую, что у меня довольно специфическая проблема с источниками данных WebLogic.У меня кластер с 3 серверами.2 из которых (назовем их бэкэнд-серверами) запускают артефакты EJB каждый (разные), в то время как 3-й использует их.Все 3 из них работают на одном компьютере.
Существует 2 источника данных, каждый из которых предназначен для одного из 2 внутренних серверов, они в основном настроены одинаково, подключаясь к одному и тому же серверу базы данных (PostgreSQL) с разными пользователями и разными базами данных.
На каждом из внутренних серверов я использую Hibernate 5.3.7 с JPA 2.2.На обоих серверах артефакты развертываются успешно. С hibernate ddl
, установленным на update
, я вижу, что в обеих базах данных таблицы для сущностей создаются успешно, и я не вижу никаких ошибок в файлах журнала.Я использую Spring Data JPA для обоих артефактов.
Основное различие между 2 артефактами EJB заключается в том, что один из них (с которыми у меня есть проблема) использует Spring Data Redis вместе с Spring Data JPA.Это позволяет мне не доверять Spring для создания репозиториев для меня, даже для JPA (afaik spring-data-redis не предоставляет реализацию для репозиториев).Я создал продюсера, который делает это для меня:
public class RepositoryConfiguration {
@Inject
private EntityManager entityManager;
@Produces
@RequestScoped
public UserRepository userRepository() {
return createRepository(UserRepository.class);
}
private <T extends Repository> T createRepository(Class<T> repositoryClass) {
RepositoryFactorySupport factory = new JpaRepositoryFactory(entityManager);
return factory.getRepository(repositoryClass);
}
}
Насколько я знаю, репозиторий redis даже не затрагивается, поэтому реализация не должна вызывать никаких проблем.
Фактическая проблема, с которой я сталкиваюсь, - это когда я пытаюсь прочитать данные из UserRepository
, я получаю исключение:
java.sql.SQLException: Transaction BEA1-0002E54B992150673EDF not active anymore. tx status = Marked rollback. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction]
at weblogic.jdbc.jts.Driver.getTransaction(Driver.java:560) ~[com.bea.core.datasource6.jar:12.2.1.3]
at weblogic.jdbc.jts.Driver.connect(Driver.java:114) ~[com.bea.core.datasource6.jar:12.2.1.3]
at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:638) ~[com.bea.core.datasource6.jar:12.2.1.3]
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:594) ~[com.bea.core.datasource6.jar:12.2.1.3]
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:587) ~[com.bea.core.datasource6.jar:12.2.1.3]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]
У меня есть компонент, создающий экземпляр EntityManager:
@PersistenceContext(name = "UsersDS")
private EntityManager em;
@Produces
@RequestScoped
public EntityManager getEntityManager() {
log.trace("EntityManager requested");
return em;
}
Рассматриваемый код, генерирующий исключение:
@Slf4j
@Stateless(name = "AuthenticationService")
public class AuthenticationServiceImpl implements AuthenticationService {
@Inject
private AuthenticationRepository authenticationRepository;
@Inject
private UserRepository userRepository;
@Inject
public AuthenticationServiceImpl() {
}
// ....
@Override
@Transactional
public TokenState getTokenState(AuthenticationToken token) {
log.trace("Searching {} in the userRepository", token);
Optional<UserEntity> user = userRepository.findByUsername(token.getPrincipal())
.filter(userEntity -> userEntity.getPassword().equals(token.getCredentials()));
if (!user.isPresent()) {
authenticationRepository.delete(token);
return TokenState.INVALID;
}
switch (user.get().getState()) {
case ACTIVE:
return authenticationRepository.existsById(token.getSessionId()) ?
TokenState.AUTHENTICATED : TokenState.UNAUTHENTICATED;
case LOCKED:
return TokenState.LOCKED;
case INACTIVE:
return TokenState.DISABLED;
default:
return TokenState.INVALID;
}
}
}
У меня есть интеграционные тесты, которые запускают базу данных in-mem H2 и встроенную базу данных Redis с управляемым вручную EntityManager, который работает без каких-либопроблемы.
Кто-нибудь может дать мне совет, как мне решить эту проблему?