@OneToMany如果属于集合

时间:2017-11-05 22:16:42

标签: java hibernate jpql cuba-platform

我正在使用古巴框架与Java JPQL

我有以下关系:

  
      
  1. Transaction_Sets
  2.   
  3. 交易
  4.   

哪里

Transaction Entity
      @ManyToOne
        @JoinColumn(name = "TRANSACTION_SET_ID")
        @OnDelete(DeletePolicy.DENY)
        protected Transaction_Set transaction_Set;
Transaction_Set entity  
        @OneToMany(mappedBy = "transaction_Set", cascade = CascadeType.REMOVE)
        @OnDeleteInverse(DeletePolicy.DENY)
        protected List<Transaction> transactions;

我尝试了很多@的组合但是由于某种原因它不能正常工作。我想要它做的就是:

  
      
  1. 如果交易属于Transaction_Set,则停止删除交易   每当我尝试删除它的交易时   删除它并将其从transaction_set中删除。
  2.   
  3. 删除transacion_set时删除transaction_set的所有事务。
  4.   

Number(2)正在运行。数字(1)我无法解决......

过去一天,我一直把头发拉过来。

我这样做了吗?我认为这可能与古巴框架的设立方式有关。

1 个答案:

答案 0 :(得分:2)

明显的设置如下:

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

但它不起作用,因为您的要求是矛盾的:交易上的DENY策略将阻止从TransactionSet端删除CASCADE。可能无法使用@OnDelete@OnDeleteInverse注释在ORM级别上解决问题,但您可以实现AfterDeleteEntityListener中的一个限制,该限制在ORM已完成所有工作时运行

因此映射应如下(仅保留第一个限制):

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