Сохранение сущности JPA с использованием простого EntityManager при весенней загрузке в @PostConstruct - PullRequest
0 голосов
/ 17 июня 2019

У меня есть минимальное весеннее загрузочное приложение, состоящее из 3 классов: Entity, компонента, который пытается заполнить базу данных в @PostConstruct, и класса приложения. Ничего другого.

@SpringBootApplication
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

@Component
@Transactional
public class Initializer {
    @Autowired
    EntityManager em;

    @PostConstruct
    public void populate() {
        em.persist(new MyEntity());
    }
}

@Entity
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
}

Когда я запускаю приложение, я получаю javax.persistence.TransactionRequiredException: нет EntityManager с фактической транзакцией, доступной для текущего потока - не может надежно обработать «постоянный» вызов

Я не единственный, кто когда-либо получал эту ошибку, и я прочитал много постов, но не нашел волшебного решения.

Если я автоматически подключу EntityMananagerFactory и вместо этого сделаю:

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(new MyEntity());
em.getTransaction().commit();
em.close();

Это работает. Вопрос: есть ли более простой способ (разместить правильную аннотацию в нужном месте), чтобы получить EntityManager, который может сохранять сущность? У меня есть веские причины не создавать хранилище (я пытался делать это, и это работает).

С наилучшими пожеланиями, Йенс

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Итак, после того, как я попробовал много разных вещей, я думаю, что нашел рабочее решение, где инициализация выполняется в обработчике ApplicationReadyEvent, а не в методе @PostConstruct:

@Component
public class Initializer {

    @PersistenceContext
    EntityManager em;

    @EventListener(ApplicationReadyEvent.class)
    @Transactional
    public void init() {
        em.persist(new MyEntity());
    }
}

Рабочий пример:https://github.com/djarnis73/spring-boot-db-init-with-jpa-entity-manager

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

Насколько я понимаю, @PostConstruct вызывается при запуске приложения, когда мы хотим инициализировать bean-компоненты и конфиги. Я думаю, что @PostConstruct - не то место, где можно это сделать.

Однако вы можете использовать @PersistenceContext для вашего entityManger вместо автоматического подключения.

...