Search code examples
javaspring-bootjpaentitymanagerspring-transactions

Persisting JPA entity using plain EntityManager in spring boot in @PostConstruct


I have a minimal spring boot application, consisting of 3 classes: an Entity, a component that tries to populate db in @PostConstruct and an application class. Nothing else.

@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;
}

When I run the application I get an javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

I'm not the only one ever getting that error and I read a lot of the posts, but did not find a magic solution.

If I autowire an EntityMananagerFactory and instead do:

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

It works. Question is: Is there a simpler way (place the right annotation at the right spot) to get an EntityManager that can persist an entity? I have good reasons for not creating a repository (I tried doing that and that works).

Best regards Jens


Solution

  • So after trying a lot of different stuff, I think that I found a working solution, where the initalization is done in an ApplicationReadyEvent handler instead of in a @PostConstruct method:

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

    Working example: https://github.com/djarnis73/spring-boot-db-init-with-jpa-entity-manager