2013-09-16 2 views
2

Метод saveUser не сохраняет изменение имени пользовательского объекта, когда у меня есть несколько операций внутри одного метода. Если я использую @Transactional (распространение = Propagation.REQUIRED) поверх метода службы saveUser, он отлично работает. Когда другой класс создает новый объект User и устанавливает все его значения и вызывает метод createUser, он отлично работает. Зачем мне @Transactional для метода saveUser? В каких случаях мне нужно включить @Transactional? Я использую Spring Data и JPA (Hibernate impl). Есть идеи?Данные о Spring JPARepository и @Transactional для нескольких операций внутри одного метода

JPA Entity:

@Entity 
public class User{ 
    @Id 
    @GeneratedValue 
    private Long id; 
    @Column 
    private String name; 

//getters/setters..etc 

} 

Spring Услуги:

@Service 
public class UserServiceImpl{ 
    @Autowired 
    UserRepository userRepository; 

    public void saveUser(Long id){ 
     User user = userRepository.findById(id); 
     user.setName("newname"); 
     userRepository.save(user); 
    } 

    public void createUser(User user){ 
     userRepository.save(user); 
    } 
} 

Spring Data JPA/Hibernate Impl Repository:

public interface UserRepository extends JpaRepository<User, Long> { 
} 

ответ

0

Вам нужны транзакции, если вы обновляете состояние базы данных (insert/update/delete), иначе вы получите такое поведение.

Даже если вы выполняете операции только для чтения в своих методах, вы должны аннотировать их @Transactional(readOnly=true), чтобы Spring могла оптимизировать транзакционный ресурс.

2

Методы в JpaRepository являются транзакционными по умолчанию (только для извлечения).

Теперь в методе saveUser(), вам нужно @Transactional, потому что вы извлекаете в User по id и обновлять его, а затем снова сохраняющиеся в базу данных. В основном, @Transactional(readOnly=true) используется при чтении еще @Transactional используется в Spring Data JPA.

User user = userRepository.findById(id); 

возвращает null в user, если пользователь не найден и user.setName("newname"); даст NullPointerException.

+0

«readonly for retrieving» - я думаю, что это предполагает, что область контекста постоянства сама по себе является транзакционной. Объекты будут оставаться прикрепленными, это контекст сохранения экземпляра EntityManager, используемый расширенным набором JpaRepository. – 8bitjunkie