一个明显的设置如下:
// 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;
但它不会起作用,因为您的要求是矛盾的:关于 Transaction 的 DENY 策略将防止从 TransactionSet 端删除 CASCADE。可能无法在 ORM 级别上使用@OnDelete
和注释解决该问题,但是您可以在 ORM 已经完成所有工作时运行@OnDeleteInverse
的其中实现限制之一。AfterDeleteEntityListener
所以映射应该如下(只保留第一个限制):
// Transaction
@OnDelete(DeletePolicy.DENY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TRANSACTION_SET_ID")
protected TransactionSet transactionSet;
// TransactionSet
@OneToMany(mappedBy = "transactionSet")
protected List<Transaction> transactions;
还有实体监听器(不幸的是,你必须在这里使用纯 SQL):
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);
}
}
}