I have a customer which has an association to a customerBudget entity. A CustomerEntityListener will create a customerBudget entity.
I get the following error:
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].
the code in onAfterInsert(Customer entity)
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);
How can I create and persist Entites in an EntityListener?
Annotation Type EntityListenersSpecifies the callback listener classes to be used for an entity or mapped superclass. This annotation may be applied to an entity class or mapped superclass. Since: Java Persistence 1.0.
You can implement BeforeInsertEntityListener
interface and create a new entity in the current persistence context via EntityManager
.
The listener may look as follows:
@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);
}
}
The new entity will be saved to the database on the transaction commit together with the Customer.
The Metadata.create()
method is the preferred way to instantiate entities - for entities with integer identifiers it assigns an ID from a sequence; it also handles entity extension if needed.
Entity listeners work in the transaction that saves the entity, which allows you to make atomic changes in your data - everything will be either saved or discarded together with the entity the listener is invoked on.
Unlike EntityManager
, DataManager
always creates a new transaction. So you should use it in an entity listener only if you really want to load or save entities in a separate transaction. I'm not sure why you get this particular exception, but your code looks weird: you load an instance of Customer which is in the database instead of using the instance which is passed to the listener. When I tried to run your code on HSQLDB, the server went to infinite lock - the new transaction inside DataManager
waits until the current transaction saving the Customer is committed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With