An obvious setup would be the following:
// Transaction
@OnDelete(DeletePolicy.DENY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TRANSACTION_SET_ID")
protected TransactionSet transactionSet;
// TransactionSet
@OnDelete(DeletePolicy.CASCADE) // won't work
@OneToMany(mappedBy = "transactionSet")
protected List<Transaction> transactions;
But it won't work because your requirements are contradictory: DENY policy on Transaction will prevent CASCADE deletion from the TransactionSet side. Probably the problem cannot be solved on the ORM level with @OnDelete
and @OnDeleteInverse
annotations, but you can implement one of the restrictions in an AfterDeleteEntityListener
which is run when ORM has already done all its job.
So the mapping should be as follows (keep only the first restriction):
// Transaction
@OnDelete(DeletePolicy.DENY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TRANSACTION_SET_ID")
protected TransactionSet transactionSet;
// TransactionSet
@OneToMany(mappedBy = "transactionSet")
protected List<Transaction> transactions;
And the entity listener (unfortunately you have to use plain SQL here):
package com.company.sample.listener;
import com.haulmont.bali.db.QueryRunner;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.global.TimeSource;
import com.haulmont.cuba.core.global.UserSessionSource;
import com.haulmont.cuba.core.sys.persistence.DbTypeConverter;
import org.springframework.stereotype.Component;
import com.haulmont.cuba.core.listener.AfterDeleteEntityListener;
import java.sql.Connection;
import java.sql.SQLException;
import com.company.sample.entity.TransactionSet;
import javax.inject.Inject;
@Component("sample_TransactionSetEntityListener")
public class TransactionSetEntityListener implements AfterDeleteEntityListener<TransactionSet> {
@Inject
private TimeSource timeSource;
@Inject
private UserSessionSource userSessionSource;
@Inject
private Persistence persistence;
@Override
public void onAfterDelete(TransactionSet entity, Connection connection) {
QueryRunner queryRunner = new QueryRunner();
DbTypeConverter dbTypeConverter = persistence.getDbTypeConverter();
try {
queryRunner.update(connection,
"update SAMPLE_TRANSACTION set DELETE_TS = ?, DELETED_BY = ? where TRANSACTION_SET_ID = ?",
new Object[]{
dbTypeConverter.getSqlObject(timeSource.currentTimestamp()),
userSessionSource.getUserSession().getCurrentOrSubstitutedUser().getLoginLowerCase(),
dbTypeConverter.getSqlObject(entity.getId())
});
} catch (SQLException e) {
throw new RuntimeException("Error deleting related transactions ", e);
}
}
}