2016-04-26 20 views
6

Mam klienta, który ma powiązanie z jednostką CustomerBudget. CustomerEntityListener utworzy encję CustomerBudget.Utwórz encję za pomocą EntityListener

pojawia się następujący błąd:

IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: de.company.entity.Customer-c4775b5b-413b-0567-3612-e0860bca9300 [new,managed]. 

kod w onAfterInsert (podmiot klienta)

LoadContext<Customer> loadContext = LoadContext.create(Customer.class); 
    loadContext.setId(entity.getId()); 
    Customer customer = dataManager.load(loadContext); 

    CustomerBudget customerBudget = new CustomerBudget(); 
    customerBudget.setCustomer(customer); 

    CommitContext commitContext = new CommitContext(customerBudget); 
    dataManager.commit(commitContext); 

Jak mogę tworzyć i utrzymywać udziałów w jednostkach w EntityListener?

Odpowiedz

7

Można zaimplementować interfejs BeforeInsertEntityListener i utworzyć nowy obiekt w bieżącym kontekście utrwalania za pośrednictwem EntityManager.

Słuchacz może wyglądać następująco:

@Component("demo_CustomerEntityListener") 
public class CustomerEntityListener implements BeforeInsertEntityListener<Customer> { 

    @Inject 
    private Metadata metadata; 

    @Inject 
    private Persistence persistence; 

    @Override 
    public void onBeforeInsert(Customer entity) { 
    CustomerBudget customerBudget = metadata.create(CustomerBudget.class); 
    customerBudget.setCustomer(entity); 
    persistence.getEntityManager().persist(customerBudget); 
    } 
} 

Nowy podmiot będzie zapisany w bazie danych na temat transakcji popełnić wspólnie z Klientem.

Metoda jest preferowanym sposobem tworzenia instancji - dla jednostek z liczbami całkowitymi przydziela identyfikator z sekwencji; w razie potrzeby obsługuje także rozszerzenie jednostki.

Detektory encji działają w transakcji, która zapisuje encję, co umożliwia wprowadzanie zmian atomowych w danych - wszystko zostanie zapisane lub odrzucone wraz z encją, na której jest wywoływany detektor.

W przeciwieństwie do EntityManager, DataManager zawsze tworzy nową transakcję. Powinieneś więc użyć go w detektorze encji, tylko jeśli naprawdę chcesz załadować lub zapisać jednostki w oddzielnej transakcji. Nie jestem pewien, dlaczego otrzymujesz ten szczególny wyjątek, ale twój kod wygląda dziwnie: ładujesz instancję klienta, która jest w bazie danych, zamiast używać instancji, która jest przekazywana do detektora. Kiedy próbowałem uruchomić twój kod na HSQLDB, serwer wszedł w nieskończoną blokadę - nowa transakcja wewnątrz DataManager czeka, aż zostanie zapisana bieżąca transakcja zapisująca Klienta.

Powiązane problemy