2016-04-26 13 views
6

Ich habe einen Kunden, der eine Zuordnung zu einer customerBudget-Entität hat. Ein CustomerEntityListener erstellt eine customerBudget-Entität.Entität mithilfe von EntityListener erstellen

bekomme ich folgende Fehlermeldung:

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

der Code in onAfterInsert (Customer-Entität)

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

Wie kann ich und anhalten entites in einem EntityListener?

Antwort

7

Sie können die Schnittstelle BeforeInsertEntityListener implementieren und eine neue Entität im aktuellen Persistenzkontext über EntityManager erstellen.

Der Zuhörer kann wie folgt aussehen:

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

Das neue Unternehmen wird in die Datenbank über die Transaktion mit dem Kunden verpflichten zusammen gespeichert werden.

Die Methode Metadata.create() ist die bevorzugte Methode zum Instanziieren von Entitäten - für Entitäten mit Ganzzahlbezeichnern weist sie eine ID aus einer Sequenz zu; Bei Bedarf wird auch die Entitätserweiterung behandelt.

Entity-Listener arbeiten in der Transaktion, die die Entität speichert, wodurch Sie atomare Änderungen an Ihren Daten vornehmen können - alles wird zusammen mit der Entität gespeichert oder verworfen, für die der Listener aufgerufen wird.

Im Gegensatz zu EntityManager erstellt DataManager immer eine neue Transaktion. Sie sollten es also nur dann in einem Entity-Listener verwenden, wenn Sie Entitäten in einer separaten Transaktion wirklich laden oder speichern möchten. Ich bin nicht sicher, warum Sie diese spezielle Ausnahme erhalten, aber Ihr Code sieht komisch aus: Sie laden eine Instanz von Customer, die sich in der Datenbank befindet, anstatt die Instanz zu verwenden, die an den Listener übergeben wird. Als ich versuchte, Ihren Code auf HSQLDB auszuführen, ging der Server in die Endlossperre - die neue Transaktion innerhalb von DataManager wartet, bis die aktuelle Transaktion, die den Kunden speichert, festgeschrieben wurde.