Проверка существования в транзакции в Hibernate - PullRequest
0 голосов
/ 18 октября 2011

У меня похожая проблема с человеком, который разместил это сообщение на весенних форумах: http://forum.springsource.org/archive/index.php/t-20943.html

В основном я пишу функцию автоматической регистрации для веб-сайта, на котором я работаю.Если пользователь существует в сторонней базе данных, из которой мы переносим пользователей, а не в нашей БД, то при входе в систему автоматически создается пользователь в нашей БД.

Для этого мне сначала нужно попытаться пройти аутентификацию.пользователь вошел в систему с адресом электронной почты и паролем.Если это не удается, я проверяю стороннюю БД и пытаюсь создать пользователя, используя эту информацию.Как и в приведенной выше ссылке, кажется, что эта проверка существования, сопровождаемая вставкой, приводит к тому, что Hibernate помечает метод как только откат.

Я пытался использовать Transactional require_New при проверке существования, чтобы заставитьновая транзакция, я надеялся, что эта транзакция будет помечена как откат только вместо родительской транзакции, но это не сработало.

Кто-нибудь может посоветовать, как это сделать?Ссылка выше предлагает вставить и использовать ошибку дублирующего ключа в качестве проверки того, что пользователь уже существует, но это кажется грязным и потребует значительного изменения.

Кстати, мы используем Hibernate, Spring и Annotations для обработки транзакций.

Ответы [ 2 ]

0 голосов
/ 20 октября 2011

Решение, которое я нашел, состоит в том, чтобы разделить соответствующие разделы на отдельные транзакции.В моем случае я проверяю, существует ли пользователь, если он не существует, но делает это в моей сторонней БД, создающей его.Это означает, что если аутентификация не удалась, создание нового пользователя не откатывается, но если это требуется, его можно разделить по-разному, поэтому методы create и authenticate находятся в одном транзакционном методе.

public void login(String username, String password)
{
   User user = null;
   try {
      user = userHelper.findUserByUsername(username);
   } catch (UserNotFoundException e) {
      log.warn(e);
      if (integrationLayer.checkUserExists(username))
      {
         user = userHelper.createUser(username, password);
      }
      else
      {
         return false;
      }
   }

   return userHelper.authenticate(user, password);
}

@Transactional
public User userHelper.findUserByUsername(String Username)
{
   ... find and return user ...
   ... throw user not found exception if not found ...
}

@Transactional
public User userHelper.createUser(String Username, String Password)
{
   ... create and return the new user ...
}


@Transactional
public Boolean userHelper.authenticate(String Username, String Password)
{
   ... authenticate the user ...
}

@Transactional
public Boolean integrationLayer.checkUserExists(String username)
{
   ... if the user exists in the third party DB return true ...
}
0 голосов
/ 18 октября 2011

Предполагая, что метод входа в систему вызывает исключение, вы можете исправить это, добавление опции noRollbackFor в ваш атрибут @Transactional в методе проверки существования.

@Transactional(noRollbackFor=SecuirtyExcepion.class)
public boolean authenticate(String email,String password) throws SecurityException {

}

@Transactional
public void someMethod() {
  try {
   // without noRollbackFor this would result in transaction being marked as 
   // rollback only 
    authenticate(email,password); 

  } catch(SecurityException e) {
    // create user

  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...