2009-07-16 12 views
35

W WZP, czy jest jakiś sposób można replikować Hibernate saveOrUpdate behavior,W jaki sposób można zreplikować saveOrUpdate Hibernate w JPA?

saveOrUpdate 

public void saveOrUpdate(Object object) 
        throws HibernateException 

    Either save(Object) or update(Object) the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking). 

    This operation cascades to associated instances if the association is mapped with cascade="save-update". 

    Parameters: 
     object - a transient or detached instance containing new or updated state 
    Throws: 
     HibernateException 
    See Also: 
     save(Object), update(Object) 

który zasadniczo sprawdza, czy obiekt już istnieje w bazie danych i albo aktualizacje obiekt jako musi być albo zapisuje nową instancję obiekt.

Wczytanie bezobsługowych plików JPA jest dobre, ale naprawdę brakuje mi tej metody ze stanu hibernacji. Jak doświadczają tego doświadczeni programiści WZP?

+0

Co powiesz na sprawdzenie, czy "klucz podstawowy" jest pusty? –

Odpowiedz

27

Spróbuj użyć metody EntityManager.merge - jest to bardzo podobne.

Istnieje doskonały opis różnic w blogu Xebii: "JPA Implementation Patterns: Saving (Detached) Entities."

+6

To dla mnie duże zainteresowanie: "Podczas aktualizacji istniejącego obiektu nie wywołujemy żadnej metody EntityManager, dostawca JPA automatycznie aktualizuje bazę danych w czasie przepłukiwania lub zatwierdzania." –

+1

Link nie działa. Oto nowy: http://blog.xebia.com/jpa-implementation-patterns-saving-detached-entities/ – Dmitry

5

Problem z metodą opisaną w artykule, do którego Pablojim jest powiązany, polega na tym, że nie obsługuje bardzo dobrze generowanych kluczy głównych.

Rozważ utworzenie nowego obiektu encji ORM, możesz podać te same dane, co istniejący wiersz w tabeli bazy danych, ale jeśli się nie mylę, menedżer encji nie rozpoznaje ich jako tego samego wiersza, dopóki nie zostaną ten sam klucz podstawowy, który w jednostce, która używa kluczy generowanych automatycznie, nie można uzyskać, dopóki nie przejdziesz do bazy danych.

Oto moja obecna praca w tej sytuacji;

/** 
* Save an object into the database if it does not exist, else return 
* object that exists in the database. 
* 
* @param query query to find object in the database, should only return 
* one object. 
* @param entity Object to save or update. 
* @return Object in the database, whither it was prior or not. 
*/ 
private Object saveOrUpdate(Query query, Object entity) { 
    final int NO_RESULT = 0; 
    final int RESULT = 1; 

    //should return a list of ONE result, 
    // since the query should be finding unique objects 
    List results = query.getResultList(); 
    switch (results.size()) { 
     case NO_RESULT: 
      em.persist(entity); 
      return entity; 
     case RESULT: 
      return results.get(0); 
     default: 
      throw new NonUniqueResultException("Unexpected query results, " + 
        results.size()); 
    } 
} 
+1

scalić i saveOrUpdate są powierzchownie podobne, ale nie takie same. Semantyka ma istotne różnice. – skaffman

+0

@skaffman, myślisz, że moje podejście jest wadliwe? Czy mógłbyś rzucić jakąś konstruktywną krytykę na mój sposób? Jestem dzieckiem w lesie dla tego WZP. –

+0

Po prostu znalazłem ten stary wątek i wdrażam coś takiego, z wyjątkiem nowych JĘZYKÓW JĘZYKOWYCH. Dzięki. – oberger

Powiązane problemy