我对实体框架相当新,并且不明白为什么我的实体无法正确保存。
编辑:
我会尽快尝试出这个测试代码,看看它是否有效:
@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 ...]
}
答案 0 :(得分:0)
代码有效,该字段恰好是默认值。
用简单的方法测试后,另一个实体也被保存到数据库中。然后我将断点放入原始代码中,如果实体的新值不同于默认值,则该断点只会被破坏。该程序在没有断点的情况下转换了所有内容。
所以,我查找了我转换的数据库,看看内容是什么。令我惊讶的是,它始终为零,默认值。
这很尴尬。我很确定,我误解了一些东西,编码错了。