2017-02-13 8 views
1

Как создать собственный метод из Spring JPA Repository, который разделяет функции вставки и обновления? Скажем, создать метод для вставки и метод обновления для обновления.Spring JPA Repository - отдельный способ вставки и обновления

Дополнительный вопрос: Почему Spring JPA Repository не разделяет эти методы по дизайну?

Моя текущая реализация - Создать проверку на уровне сервиса.

Мой Repository

public interface UserRepository extends CrudRepository<User, Integer> {} 

Моя_служба

@Service 
public class UserService { 
    public void addUser(User user) { 
     if (!userRepository.exists(user.getId())) { 
      userRepository.save(user); 
     } 
    } 

    public void updateUser(int id, User user) { 
     if (userRepository.exists(user.getId())) { 
      userRepository.save(user); 
     } 
    } 
} 
+0

Вы можете попытаться @Override сохранить метод при создании хранилища и поэтому затем создать метод обновления. Но я не думаю, что это хорошее решение. – Mike

+0

Зачем вам это нужно, чего вы хотите достичь? @Mike: вы не можете переопределить его, так как метод сохранения написан в интерфейсе CrudRepository . –

+0

Я пробовал его перед тем, как писать, и он компилировался, поэтому я подумал, что вы можете это сделать. Это была попытка, но, как я уже сказал, это нехорошее решение. – Mike

ответ

2

Ее можно обеспечить собственное расширение к Standart пружинных хранилищ данных:

Добавление пользовательского поведения ко всем хранилищам :

https://docs.spring.io/spring-data/data-commons/docs/current/reference/html/#repositories.custom-behaviour-for-all-repositories

Вы могли бы, например, реализовать функцию блокировки

void lock(T entity, LockModeType lockModeType); 

Но в вашем случае, я предлагаю, чтобы просто оставить чеки прочь, вызвать SpringDataRepository уже проверяет его новый или нет. Если есть идентификатор, он все равно существует, потому что вы, надеюсь, не создадите свои собственные идентификаторы. Это все часть контракта весной данных:

SimpleJpaRepository:

@Transactional 
public <S extends T> S save(S entity) { 

    if (entityInformation.isNew(entity)) { 
     em.persist(entity); 
     return entity; 
    } else { 
     return em.merge(entity); 
    } 
} 
+0

Эта проверка только для проверки новых и текущих данных, поэтому Spring JPA не будет автоматически отменять ее. Из-за этой проверки мне нужно создать много валидаций всех Сервисов. Тогда я думаю, что есть много шаблонов проверки вставки и обновления, поэтому мне нужно упростить в пользовательском репозитории. –

+0

Я бы сказал, что вам это действительно не нужно, потому что если у вас есть новый объект, идентификатор не будет установлен.Как таковой, он сохраняется (isNew() check in save()). Если у вас есть уже существующий, у него будет id, и jpa попытается его сохранить. Сохранение может иметь больше характеристик, таких как оптимистическая блокировка, которые помогают находить параллельные манипуляции -> https://vladmihalcea.com/2015/01/12/a-beginners-guide-to-java-persistence-locking/ – Dudelilama

+0

Да, ID не будет установлен. Но вы не можете запретить пользователю не вводить или добавлять идентификатор. Пример метода create: HTTP POST/foo {id: 1, attr: A}, если вы просто используете save(), существующий объект будет переопределен (merge()) новым. Поэтому мне нужно добавить проверку, которая запрещает пользователям, которые используют метод create, поэтому он не может обновлять данные с помощью функции save(). –