Как добавить образцы данных в базу данных с помощью springboot?

#java #spring-boot #spring-data-jpa

#java #spring-boot #spring-data-jpa

Вопрос:

У меня есть приложение Spring Boot с JPA Spring Data и двумя объектами, сопоставленными с базой данных. Мое приложение настроено на воссоздание базы данных при каждом запуске. Теперь я хочу создать несколько экземпляров этих POJO, сохранить их в базе данных, чтобы у меня были некоторые данные для тестирования моего приложения в текущем процессе разработки.

Каков наилучший способ сделать это?

Что я пробовал до сих пор: мой класс для добавления образцов данных

 public class DBSampleAdditor {
    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void addSampleData() {
        // creating POJO instances and persist them with em.perists()
    }
}
  

Я попытался вызвать эти функции в основном из моего ApplicationClass

 @SpringBootApplication()
public class ApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
    }
}
  

Это вообще не сработало, поскольку EntityManager так и не получил экземпляр из модуля сохранения.

Я также пытался создать CommandLineRunner:

 @Component
public class PTCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("Adding sample data...");
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
    }
}
  

Но, похоже, это никогда не вызывалось в процессе запуска.

Ответ №1:

Вы можете использовать метод с @PostConstruct с @Component для вставки данных при запуске.

@PostConstruct будет вызван после создания компонента, внедрения зависимостей, установки всех управляемых свойств и до того, как компонент будет фактически установлен в область видимости.

Просто введите свой репозиторий базы данных в класс, помеченный @Component, и вызовите введенный репозиторий базы данных внутри метода, помеченного @PostConstruct

Пример:

 @Component
public class DbInit {
 
    @Autowired
    private UserRepository userRepository;
 
    @PostConstruct
    private void postConstruct() {
        User admin = new User("admin", "admin password");
        User normalUser = new User("user", "user password");
        userRepository.save(admin, normalUser);
    }
}
  

Комментарии:

1. Я пробовал это, но метод, который аннотируется с помощью @PostConstruct, никогда не вызывается.

2. Хорошо — я исправил это, забыл включить обработку аннотаций внутри IntelliJ. Для меня это работает просто отлично.

Ответ №2:

Для использования управляемых компонентов Spring, таких как EntityManager объекты, необходимо использовать spring Beans , что в основном означает, что они создаются внутри контекста Spring и могут использовать контейнер IoC.

В приведенном выше примере запуск DbSampleAdditor класса из метода main находится вне контекста Spring, поэтому такие компоненты, как PersistenceContext , не будут введены.

Один довольно простой способ сделать это внутри контекста spring — добавить ApplicationListener для ApplicationReadyEvent

 @Component
class Initialise implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    private final DbSampleAdditor db;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        db.addSampleData();
   }
}
  

Когда срабатывает событие готовности приложения, настраивается вся необходимая проводка spring bean, поэтому, когда он запускает addSampleData метод, такие вещи, как EM, можно использовать.

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

Комментарии:

1. Нужно ли мне в какой-то момент сообщать моему приложению, что этот класс существует, или я должен поместить его в пакет, который находится в определенном отношении к моему классу приложения? Инициализатор никогда не вызывается.

Ответ №3:

Вместо создания объекта DBSampleAdditor попробуйте автоматически подключить его, чтобы он был доступен при запуске приложения. @Autowired DBSampleAdditor DBSampleAdditor Затем вы пытаетесь добавить образцы данных в метод run