2012-02-24 10 views
6

Witam Mam proste DAO z poniższą funkcją.JPA EntityManager persist() powoduje, że obiekt wygląda na odłączony, mimo że został zgłoszony błąd.

public element createElement(Element e){ 

    em.persist(e); 
    em.flush(); 

    return e; 
} 

tabela Podmiot posiada wyjątkową presję na pary (typ, wartość) i mam test poniżej:

public void testCreateElement() throws DataAccessException { 
     // Start with empty Element table 

     Element e = new Element(); 
     e.setType(myType.OTHER); 
     e.setValue("1"); 
     dao.createElement(e); 

     e = new Element(); 
     e.setType(MyType.OTHER); 
     e.setValue("1"); 
     try{ 
       // this should violate unique constraint of database. 
       dao.createElement(e); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } 

     e.setValue("2"); 
     try{ 
      // I expect this to work as there is no element with these values. 
      dao.createElement(e); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } 
    } 

Mój pierwszy złapany błąd zdarza się, kiedy spodziewać, ponieważ wiem, że” m naruszenie ograniczenia, drugi try/catch nie powinny rzucać się błąd o ile mi wiadomo, ale robi, co mam Jej to:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.mypackage.Element 

więc wydaje nazywając utrzymują() na " e "nawet jeśli nie było trwałe spowodował hibernację, by sądzić, że jest oderwaną jednostką.

Jest to denerwujące, ponieważ funkcje te są wykorzystywane przez front interfejsu JSF, który zajmuje się wyjątkiem Vault Constration, ale celowo trzyma się obiektu, aby użytkownik mógł zmienić jedno z pól i spróbować ponownie, a oni otrzymają błąd oddzielonego obiektu.

Czy to zachowanie jest błędem hibernacji, ponieważ uważam, że nie powinno tak być naprawdę? Czy jest jakiś sposób obejścia tego na poziomie DAO, aby przetrwać wygrał, traktować mój obiekt jako odłączony, jeśli tak naprawdę nie jest trwały?

Chodzi,

Glen x

+0

Po prostu do uśmiechu, co się stanie, jeśli utworzysz nowy element i ustawisz odpowiednie wartości przed ostatnim wywołanym parametrem createElement? –

+0

Wszystko idzie dobrze. – Link19

+0

Czy to pomaga? Jeśli nie, może to działać ... e.setValue (1); e = dao.createElement (e); (<- zawiedzie), ale potem e.setValue (2); edao.createElement (e); (<- zadziała, mam nadzieję). –

Odpowiedz

3

Wyjątek wyrzucane przez hibernacji nie do odzyskania. Jedyną rzeczą, którą powinieneś zrobić, gdy wystąpi taki wyjątek, jest wycofanie transakcji i zamknięcie sesji. Stan sesji (i jej elementów) po takim wyjątku jest niestabilny.

Jeśli chcesz zachować kopię elementu nietkniętego, użyj merge() zamiast persist() lub sklonuj element przed jego utrwaleniem.

Należy zauważyć, że wyjątek jest oczekiwany, ponieważ gdy stan hibernacji utrzymuje się i opróżnia encję, rozpoczyna się od wygenerowania identyfikatora i przypisania identyfikatora do encji, a następnie wstawienia wiersza, co powoduje wyjątek. Tak więc, po wystąpieniu wyjątku, jednostka ma przypisany identyfikator, a zatem jest uważana za obiekt oddzielony przez Hibernate. Możesz spróbować zresetować ID na wartość null i sprawdzić, czy działa, ale wolałbym klonować obiekt przed lub używając scalania.

Powiązane problemy