verschillende manieren om de EntityManager te krijgen

Het gebruikelijke idioom dat ik zie voor het maken van de EntityManager is ongeveer als volgt:

public class BaseDao {

private static final String PERSISTENCE_UNIT_NAME = "Employee";
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

public EntityManager getEntityManager() {
      return factory.createEntityManager();
    } 
}

dan wordt het als volgt gebruikt:

Employee emp = new Employee();
emp.setName("Joe M");
getEntityManager().persist(emp);

Vraag is waarom het niet op deze manier doen:

public class BaseDao{
    private static final String PERSISTENCE_UNIT_NAME = "Employee";
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    private EntityManager entityManager = null;


public void setEntityManger() {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    this.entityManager = factory.createEntityManager();

    }

    public EntityManager getEntityManager() {
        return this.entityManager;
    }
}

Met andere woorden, is er een noodzaak om altijd de entiteitbeheerder te krijgen via factory.createEntityManager ()? of kan het worden gemaakt als een instantie (of zelfs statische) variabele en zo worden opgehaald?

Ter verduidelijking, ik heb het over een omgeving die geen EJB- of Spring-containers gebruikt.

Bedankt.

27

2 antwoord

Er zijn twee manieren om instanties van EntityManager te maken. Eén manier is voor SDK-applicaties, en ik gebruik deze manier veel in unit-testen. Dit is wat je hebt in je voorbeeld:

EntityManagerFactory factory = 
  Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

In Enterprise-toepassingen laat u de container ze voor u maken en injecteert u ze wanneer dat nodig is.

EntityManager is just a wrapper around a JDBC connection. It's very light weight and can be created and destroyed without performance penalty.

Houd er rekening mee dat de EntityManager niet threadveilig is. Als u dus één exemplaar hebt, moet u mogelijk de toegang hiertoe synchroniseren. Zie transaction basics voor meer informatie.


Hier is hoe ik het zou doen (ongeveer):

public class BaseDao{
  private static final String PERSISTENCE_UNIT_NAME = "Employee";
  private static EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

  public void create(MyEntiy person){
    EntityManager em = factory.createEntityManager();
    em.getTransaction().begin();
   //do what ever you need 
    em.getTransaction().commit();
    em.close();
  }

 //add more methods to the dao.
}

Als u deze prototypes gereed hebt, kunt u een generieke DAO gebruiken.

12
toegevoegd
Nee, het zal niet garenveilig zijn, maar de container creëert een nieuwe wanneer dat nodig is (ik zou het mis kunnen hebben), dus het ziet eruit als draadgarens. Als u geen Enterprise-omgeving gebruikt, zie ik geen probleem bij het maken van één statische instantie van de fabriek EntityManagerFactory en noem ik dit om exemplaren van EntityManager te verkrijgen wanneer dat nodig is. En niet foreget om ze na elke transactie te sluiten. Deze thread toont een code die nuttig voor u kan zijn. stackoverflow.com/questions/7329873/…
toegevoegd de auteur Mansour, de bron
bedankt - ik heb een opmerking toegevoegd aan mijn oorspronkelijke post waarin ik duidelijk maakte dat ik niet in een Enterprise-omgeving werk, daarom is containerinjectie niet beschikbaar. Ik merk wel uw opmerking over thread-safety op.
toegevoegd de auteur jayjay, de bron
RE thread-safety - Ik neem aan dat u naar mijn voorbeeld verwijst, omdat een EntityManager die wordt ingespoten en beheerd door een container, thread-safe is.
toegevoegd de auteur jayjay, de bron
Mansour, mijn vraag ging niet over een statische EMF en daarna werd createEntityManager() erop aangeroepen (dit is het eerste voorbeeld in mijn post en ook het voorbeeld waarnaar je in de link verwijst). Mijn vraag ging over het maken van een instantie of statische EM en dat vervolgens te gebruiken.
toegevoegd de auteur jayjay, de bron

Vandaag zou je waarschijnlijk eens naar lente-data en @PersistanceUnit moeten kijken om je EntityManager te beheren.

Een EntityManager is meer dan alleen een wrapper een wrapper voor een JDBC-verbinding. Het definieert de reikwijdte van een persistentiecontext, die de werkeenheid definieert die moet worden uitgevoerd wanneer een transactie wordt vastgelegd (of wanneer u query's naar de database wegspoelt). In een persistentie-context bent u er ook zeker van dat een gegeven entiteit in de database hetzelfde Java-object zal opleveren, ongeacht of u het direct laadt of toegang hebt via een OneToMany-relatie van een andere entiteit.

Met betrekking tot de oorspronkelijke vraag over het verkrijgen van een EntityManagerFactory in een niet-voorjaarsomgeving. Je belt gewoon

Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

Deze methode is een statische fabrieksmethode, afhankelijk van uw JPA-implementatie krijgt u dezelfde instantie voor dezelfde PU, of een ondiepe wrapper die de onderliggende persistentiesessie (waarvan er één per PU is) omsluit.

1
toegevoegd