2016-04-26 9 views
6

Ho un cliente che ha un'associazione con un'entità customerBudget. Un CustomerEntityListener creerà un'entità customerBudget.Crea entità utilizzando EntityListener

ottengo il seguente errore:

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]. 

il codice a onAfterInsert (entità Customer)

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); 

Come posso creare e persistere entités in un EntityListener?

risposta

7

È possibile implementare l'interfaccia BeforeInsertEntityListener e creare una nuova entità nel contesto di persistenza corrente tramite EntityManager.

L'ascoltatore può apparire come segue:

@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); 
    } 
} 

La nuova entità sarà salvato nel database sulla transazione commit insieme al Cliente.

Il metodo Metadata.create() è il metodo preferito per creare un'istanza di entità: per le entità con identificatori interi assegna un ID da una sequenza; gestisce anche l'estensione dell'entità se necessario.

Gli ascoltatori di entità funzionano nella transazione che salva l'entità, che consente di apportare modifiche atomiche nei dati: tutto verrà salvato o scartato insieme all'entità su cui viene richiamato il listener.

A differenza di EntityManager, DataManager crea sempre una nuova transazione. Quindi dovresti usarlo in un listener di entità solo se vuoi davvero caricare o salvare entità in una transazione separata. Non sono sicuro del motivo per cui ottieni questa particolare eccezione, ma il tuo codice sembra strano: tu carichi un'istanza di Cliente che si trova nel database invece di usare l'istanza che viene passata al listener. Quando ho provato a eseguire il codice su HSQLDB, il server è passato al blocco infinito: la nuova transazione all'interno di DataManager attende fino a quando non viene eseguita la transazione corrente salvando il cliente.

Problemi correlati