关联实体未在事务

时间:2016-03-08 11:52:29

标签: java spring entity-framework repository transactional

我对实体框架相当新,并且不明白为什么我的实体无法正确保存。

编辑:

我会尽快尝试出这个测试代码,看看它是否有效:

@Transactional
public void doConvert(String lakoKod) {
    LsZFutelszHavi futelszHavi = new LsZFutelszHavi();
    //Give it values like:
    futelszHavi.setOrigKorrOssz(new BigDecimal(500));
    LsTLako lako = lsTLakoRepository.findOneByLakoKod(lakoKod);
    LsZFutelsz futelsz = lsZFutelszRepository.findOneByLsTLako(lako);
    //The modification which not get saved into tha Firebird table in the original code. Will it be saved now?
    futelsz.setSzezVegenBefOssz(new BigDecimal(100));
    futelszHavi.setLsZFutelsz(futelsz);
    lsZFutelszHaviRepository.save(futelszHavi);
}

我正在尝试从旧的DBASE数据库转换为Firebird数据库。 Firebird数据库具有由实体映射的表。我读了一个DBASE表,然后逐行转换它。

我使用@Transactional来保存DBASE表的所有转换实体,或者保存无。

我设法将每个表正确转换为新数据库,除了一个。

在其他表中,我只需要为每个记录保存一个实体,而不必修改其他类型的实体。我通常不得不创建一个Type X实体,将它连接到Type Y实体,然后保存。对于保存,我使用实体的存储库(如果重要的话,可以使用org.springframework.data.repository.PagingAndSortingRepository)

在那个特定的DBASE表中,我必须创建一个Type A实体,将它连接到Type B实体,修改Type B实体,然后保存。问题是,B类实体修改不会保存到Firebird表中。同样,我使用存储库来保存实体。

要获取B类实体,我使用它的存储库方法:

LsZFutelsz findOneByLsTLako(LsTLako lsTLako); 

我猜想,如果我将这个B类实体与它自己的存储库一起保存,它将在数据库中正确修改。它没有帮助。

请告诉我是否需要其他信息。

我在这里复制了稍微修改过的代码(删除了一些日志记录,添加了一些注释)。 LsZFutelszHavi是Type A EntityClass,LsZFutelsz是B类EntityClass。

Konverter抽象类。它是为每个DBASE表继承的

public abstract class Konverter<RepositoryType extends     CrudRepository<EntityType,Integer>, EntityType> {
protected String dbfPath;
protected DBaseTable sourceTable = null;
protected Logger logger;
protected RepositoryType repository;
protected String dBaseEncoding = DBaseTable.CP852;

public Konverter(String dbfPath, Logger logger, RepositoryType repository) {
    this.dbfPath = dbfPath;
    this.logger = logger;
    this.repository = repository;
}

/*
This method should be called, to start converting
*/
@Transactional
public void konvert() {
    try {
        /*It loads the DBASE database*/     
        File sourceFile = new File(fileName);
        sourceTable = new DBaseTable(sourceFile, dBaseEncoding);
        sourceTable.open(IfNonExistent.ERROR);

        Iterator<Record> recordIterator = sourceTable.recordIterator();            
        int count = 0;
        try {
            /*Converts the database table row by row*/
            count = konvertSorok(recordIterator);
        } catch (Exception e) {
            throw e;
        } finally {
            sourceTable.close();
        }
    }
    catch (CorruptedTableException | IOException | RuntimeException e) {
        logger.error(QsLoggerUtils.getStackTraceString(e));//e.printStackTrace();
    }

}

private int konvertSorok(Iterator<Record> recordIterator) {
    int count = 0;
    /*Converts the database table row by row*/
    while(recordIterator.hasNext())
    {
        Record record = recordIterator.next();
        /* Converting one row */
        List<EntityType> entityIterable = konvertToEntity( record );

        for (EntityType entityType : entityIterable) {
            repository.save(entityType);                
        }
        count++;
    }       
    return count;
}

/**
 * This should be implemented in the child method
 * @param record
 * @return
 */
protected abstract List<EntityType> konvertToEntity(Record record); 
}

子类,它实现了konvertToEntity方法。

public class Konvert14FutelszHavi extends Konverter<LsZFutelszHaviRepository,LsZFutelszHavi> {

private static Logger logger = LoggerFactory.getLogger(Konvert12Futalany.class);

LsZFutelszHaviRepository lsZFutelszHaviRepository;
LsTLakoRepository lsTLakoRepository; 
LsZFutelszRepository lsZFutelszRepository;
LsTEvhoRepository lsTEvhoRepository;


@Autowired
public Konvert14FutelszHavi(LsZFutelszHaviRepository lsZFutelszHaviRepository,
                            LsTLakoRepository lsTLakoRepository,
                            LsZFutelszRepository lsZFutelszRepository,
                            LsTEvhoRepository lsTEvhoRepository) throws IOException {
    super(DBaseTable.chkFile(AppKonvertLax.PATH_LSZBF, AppKonvertLax.SOURCE_FILE_FUTELSZ_HAVI), logger, lsZFutelszHaviRepository);
    dBaseEncoding = DBaseTable.CP1250;
    this.lsTLakoRepository = lsTLakoRepository;
    this.lsZFutelszHaviRepository = lsZFutelszHaviRepository;
    this.lsZFutelszRepository = lsZFutelszRepository;
    this.lsTEvhoRepository = lsTEvhoRepository;
}

@Override
protected List<LsZFutelszHavi> konvertToEntity(Record record) {
    String ukod     = record.getStringValue("UKOD").substring(1).trim();        
    BigDecimal ekaptam  = new BigDecimal(record.getNumberValue("EKAPTAM").toString());        
    BigDecimal efutkul  = new BigDecimal(record.getNumberValue("EFUTKUL").toString());              

    ArrayList<LsZFutelszHavi> returnArray = new ArrayList<LsZFutelszHavi>();
    LsTLako lsTLako = lsTLakoRepository.findOneByLakoKod(ukod);
    LsZFutelsz lsZFutelsz = lsZFutelszRepository.findOneByLsTLako(lsTLako);
    if (lsZFutelsz == null) {
        return returnArray;
    }
    /* Here is the modification in the lsZFutelsz (Type B) entity */
    lsZFutelsz.setSzezVegenBefOssz(ekaptam);

    /* From 10th month to 4th */
    for (int i=10; i!=5; i++) {
        if (i==13) { 
            i = 1;
        }
        String keyNumber = Integer.toString(i);
        if (keyNumber.length() == 1) {
            keyNumber = "0" + keyNumber;
        }
        BigDecimal fk = new BigDecimal(record.getNumberValue("FK_"+keyNumber).toString());
        LsZFutelszHavi lsZFutelszHavi = new LsZFutelszHavi();
        LsTEvho lsTEvho = lsTEvhoRepository.findOneByEvAndHo(2014, i);
        lsZFutelszHavi.setLsTEvho(lsTEvho);
        lsZFutelszHavi.setFizKorrOssz(fk);
        lsZFutelszHavi.setOrigKorrOssz(efutkul);
        /* This should be enough to save the lsZFutelsz entity modification I would think */
        lsZFutelszHavi.setLsZFutelsz(lsZFutelsz);
        returnArray.add(lsZFutelszHavi);
    }

    /* Even this does not help */
    lsZFutelszRepository.save(lsZFutelsz);

    return returnArray;
}

}

B类实体的存储库

@RepositoryRestResource(collectionResourceRel = LsZFutelszHavi.VERB_FUTELSZ, path = LsZFutelszHavi.VERB_FUTELSZ)
public interface LsZFutelszRepository extends PagingAndSortingRepository<LsZFutelsz, Integer> {
    /*-----------------------------------------------------------------------------------------------*/
    @RestResource(exported=false)
    @Modifying
    @Query(value="DELETE FROM ls_z_futelsz f WHERE f.lako_id = ?1", nativeQuery=true)
    void deleteByLako(Integer integer);
    /*-----------------------------------------------------------------------------------------------*/ 
    LsZFutelsz findOneByLsTLako(LsTLako lsTLako);
}

A类实体的存储库

@RepositoryRestResource(collectionResourceRel = LsZFutelsz.VERB_FUTELSZHAVI, path = LsZFutelsz.VERB_FUTELSZHAVI)
public interface LsZFutelszHaviRepository extends PagingAndSortingRepository<LsZFutelszHavi, Integer> {

}

实体类型A

@Entity
@Table(name="LS_Z_FUTELSZ_HAVI")
@NamedQuery(name="LsZFutelszHavi.findAll", query="SELECT l FROM LsZFutelszHavi l")
public class LsZFutelszHavi extends Audit implements Serializable {

    public static final String VERB_FUTELSZ  = "futelszamolasok";
    /*-----------------------------------------------------------------------------------------------*/
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name="GenFutelszHaviID", sequenceName="GEN_LS_Z_FUTELSZ_HAVI_ID", allocationSize= 1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="GenFutelszHaviID")
    @Column(name="HAVI_ELSZ_ID")
    private Integer haviElszId;

    @NotNull
    @Column(name="FIZ_KORR_OSSZ")
    private BigDecimal fizKorrOssz;

    @NotNull
    @Column(name="ORIG_KORR_OSSZ")
    private BigDecimal origKorrOssz;

    //uni-directional many-to-one association to LsFSzlafej
    @ManyToOne
    @JoinColumn(name="SZLA_ID")
    private LsFSzlafej lsFSzlafej;

    //uni-directional many-to-one association to LsTEvho
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="EV", referencedColumnName="EV"),
        @JoinColumn(name="HO", referencedColumnName="HO")
        })
    private LsTEvho lsTEvho;

    //bi-directional many-to-one association to LsZFutelsz
    @ManyToOne
    @JoinColumn(name="ELSZ_ID")
    private LsZFutelsz lsZFutelsz;

    public LsZFutelszHavi() {
    }
    //[... setters getters ...]
}

实体类型B

@Entity
@Table(name="LS_Z_FUTELSZ")
@NamedQuery(name="LsZFutelsz.findAll", query="SELECT l FROM LsZFutelsz l")
public class LsZFutelsz extends Audit implements Serializable {
    public static final String VERB_FUTELSZHAVI = "futelszhavi";
    /*-----------------------------------------------------------------------------------------------*/
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name="GenFutelszID", sequenceName="GEN_LS_Z_FUTELSZ_ID", allocationSize= 1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="GenFutelszID")
    @Column(name="ELSZ_ID")
    private Integer elszId;

    @NotNull
    @Column(name="LEOLV_FOGY_GJ")
    private BigDecimal leolvFogyGj = BigDecimal.ZERO;

    @NotNull
    @Column(name="LEOLV_FOGY_OSSZ")
    private BigDecimal leolvFogyOssz = BigDecimal.ZERO;

    @NotNull
    @Column(name="ELOZ_SZEZ_OSSZ")
    private BigDecimal elozSzezOssz = BigDecimal.ZERO;

    @NotNull
    @Column(name="SZEZ_VEGEN_BEF_OSSZ")
    private BigDecimal szezVegenBefOssz = BigDecimal.ZERO;

    @NotNull
    @Column(name="SZOSZT_UTAN_FENNM")
    private BigDecimal szosztUtanFennm = BigDecimal.ZERO;

    @NotNull
    @Column(name="SZOSZTANDO_KULONB")
    private BigDecimal szosztandoKulonb = BigDecimal.ZERO;

    //uni-directional many-to-one association to LsTLakok
    @ManyToOne
    @JoinColumn(name="LAKO_ID")
    private LsTLako lsTLako;

    //bi-directional many-to-one association to LsZFutelszHavi
    @OneToMany(mappedBy="lsZFutelsz", cascade={CascadeType.REMOVE})
    private List<LsZFutelszHavi> lsZFutelszHaviTetelek;

    public LsZFutelsz() {
    }
    //[... setters getters ...]
}

1 个答案:

答案 0 :(得分:0)

代码有效,该字段恰好是默认值。

用简单的方法测试后,另一个实体也被保存到数据库中。然后我将断点放入原始代码中,如果实体的新值不同于默认值,则该断点只会被破坏。该程序在没有断点的情况下转换了所有内容。

所以,我查找了我转换的数据库,看看内容是什么。令我惊讶的是,它始终为零,默认值。

这很尴尬。我很确定,我误解了一些东西,编码错了。