Spring Data - Как повторно использовать хранилище во фрагменте хранилища? - PullRequest
0 голосов
/ 15 ноября 2018

Обновление : следующее использует Spring Boot 2.1.0

У меня есть репозиторий Spring Data, и я пытаюсь предоставить ему некоторые пользовательские функции, следуя примеру фрагментов из документации .

Итак, я добавил дополнительный интерфейс в хранилище:

public interface UserRepository extends JpaRepository<User, Long>, UserExtraLogic {
    User findByFirstNameAndLastName(String firstName, String lastName);
}

с этим пользовательским интерфейсом:

interface UserExtraLogic {
    void ensureHasAccess();
}

и его реализация:

class UserExtraLogicImpl implements UserExtraLogic {
    public void ensureHasAccess() {
    }
}

Проблема в том, что я хотел бы иметь возможность использовать свои репозитории внутри UserExtraLogicImpl, чтобы я мог повторно использовать методы запросов, такие как findByFirstNameAndLastName, без необходимости писать их самостоятельно с помощью EntityManager. Итак, я попробовал это:

class UserExrtaLogicImpl implements UserExtraLogic {
    @Autowired
    private UserRepository userRepository;
}

Но тогда приложение не запускается. Я получаю исключение NullPointerException, но я думаю, что Spring просто начинает цикл, пытаясь разрешить эти зависимости.

Возможно ли то, что я пытаюсь сделать? Есть ли другой способ сделать это?

Ответы [ 4 ]

0 голосов
/ 02 июня 2019

Обратите внимание на это в документации.

Extending the fragment interface with your repository interface combines the CRUD and custom functionality and makes it available to clients.

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

  1. Добавьте ваш запрос в свой фрагмент и расширьте его в своем хранилище.Тогда в ваш сервисный метод включите агрегированный метод.В этом методе напишите свою логику.
  2. В своем пользовательском интерфейсе включите свой репозиторий и не расширяйте свой пользовательский интерфейс в репозитории.
  3. Используйте класс декоратора.Передайте все методы в хранилище и объедините пользовательскую логику с хранилищем.

Не включайте циклические зависимости, так как это не рекомендуется.

0 голосов
/ 31 мая 2019

Вы можете лениво загрузить свой репозиторий с помощью ObjectFactory<T> (Spring concept) или Provider<T> (стандарт Java API).

class UserExrtaLogicImpl implements UserExtraLogic {
    @Autowired
    private ObjectFactory<UserRepository> userRepository;

    public void soSomething() {
         userRepository().getObject().findById(xxx);
    }
}
0 голосов
/ 31 мая 2019

У меня точно такие же шаблоны кода, и я столкнулся с той же проблемой в недавнем проекте, и я наконец-то решил ее, используя @Lazy для отложенной инициализации UserRepository:

class UserExrtaLogicImpl implements UserExtraLogic {

    @Lazy
    @Autowired
    private UserRepository userRepository;

}
0 голосов
/ 15 ноября 2018

Включение репозитория

Из документации

Если вы используете конфигурацию Spring XML, у вас должно быть следующее:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

  <jpa:repositories base-package="com.acme.repositories" />

</beans>

Если вместо этого вы используете конфигурацию Java, вы должны иметь следующее:

@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {

  @Bean
  EntityManagerFactory entityManagerFactory() {
    // …
  }
}

Конфигурация репозитория

Также вам необходимо добавить аннотацию @Repository в свои репозитории:

@Repository
public interface UserRepository extends JpaRepository<User, Long>, UserExtraLogic {
    User findByFirstNameAndLastName(String firstName, String lastName);
}

1019 ** * Объяснение 1020 ** * 1021

Из документации

Используя элемент repositories, можно найти репозитории Spring Data как описано в «Создание экземпляров репозитория» . Помимо этого, это активирует перевод исключений постоянства для всех аннотированных компонентов с @Repository, чтобы разрешить JPA генерировать исключения поставщики персистентности будут преобразованы в Spring's DataAccessException иерархия.

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