0

I need a EntityManager for my some methods in Spring Data JPA. What best method for enabling this in my code:

@Service
public class MyService {
   private final EntityManager em;
   public MyService(EntityManager em) {
     this.em = em;
   }
}

Or that:

@Service
public class MyService {
   @PersistenceContext
   private EntityManager em;
}

I like first method, but I know that JPA specification declare closing EntityManager after transaction, and in first example field is final (how it can injecting again after em.close, if object is immutable)?

  • 1
    You are right! (Constructor injection has its (+dis-/)advantages, and it cannot be practiced "like religion") 1. Is probably wrong (a singleton `EntityManager`) 2. Conforms with (also modern) [documentation](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#dao-annotations). – xerx593 Mar 25 '23 at 22:17
  • 1
    @xerx593 thanks for the answer! But in JPA specification (look this question answer: https://stackoverflow.com/questions/10762974/should-jpa-entity-manager-be-closed) we need a close ```EntityManager```. How it can be singleton? Maybe I misunderstand something – Andrzej Jankowski Mar 25 '23 at 22:25
  • 1
    No, it should not be singleton ..(except if someone really wants this), but by `@Service`+`final`+constructor It is (de facto;) – xerx593 Mar 25 '23 at 22:30
  • 1
    With `@Service`+ `final` we could *better* inject `EntityManager` ...*`Factory`* (!) – xerx593 Mar 25 '23 at 22:36
  • 1
    @xerx593 I tried first method - and that’s works well, more one time. But by specification - EntityManager closing after transaction (and yes, it’s closing in spring too). But what’s a magic - if that closed - then it’s «worked out» object and we need new instance (open), but we can use EntityManager again… Is that proxy by spring? Or that’s rewriting FINAL field ? – Andrzej Jankowski Mar 25 '23 at 22:40
  • Have you "stress tested" (by multiple (remote) users)?;) No, (normally) final is final – xerx593 Mar 25 '23 at 22:45
  • 1
    @xerx593 didn’t, but I tried do more one request, and that’s was fine. This magic scares me a lot – Andrzej Jankowski Mar 25 '23 at 22:46
  • @xerx593 I found this answer in some question (https://stackoverflow.com/a/49948301/18824568). But I think that’s really magic (with proxy and other black-jackes) – Andrzej Jankowski Mar 25 '23 at 22:50
  • 1
    But if you follow the [link](https://jira.spring.io/browse/SPR-10443), it is an "open" (stupid, sorry!) "request".. :) ..and comments clearly say "you cannot constructor inject entity manager" – xerx593 Mar 25 '23 at 22:55
  • @xerx593 okey, so I think best solution «again» (I’m going to rewriting my changes back) using PersistenceContext. Thanks for this discussion and dialog! – Andrzej Jankowski Mar 25 '23 at 22:59
  • @xerx593 omg… I really interesting how they “fixed” final fields. It just doesn’t fit in my head. How they close and open EntityManager again… I think (just theory) is proxy magic – Andrzej Jankowski Mar 25 '23 at 23:08
  • 1
    ... if you're rewriting (back...sry , welcome), then also consider to introduce/use a `@Repository` layer (as documented)...to get (full) "exception translation"... (To handle these in `@service`s;) – xerx593 Mar 25 '23 at 23:15
  • 1
    But also you must admit, a test from single user in localhost is not very representative... ("Anonyme Browser" at least gives you a 2nd/multiple (http) sessions) – xerx593 Mar 25 '23 at 23:16
  • 1
    Another very specific section: https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#orm-jpa-dao – xerx593 Mar 25 '23 at 23:34

0 Answers0