2016-03-08 2 views
0

Я довольно новичок в инфраструктуре сущностей и не понимаю, почему моя сущность не будет сохранена правильно.Связанная сущность не сохраняется в транзакции

редактировать:

Постараюсь из этого тестового кода в ближайшее время, и посмотреть, если он работает:

@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, либо сохранить их.

Мне удалось преобразовать каждую таблицу правильно в новую базу данных, кроме одной.

В других таблицах мне нужно было сохранить только одно сущность на запись и не нужно было изменять объекты другого типа. Обычно мне приходилось создавать объект типа X, подключать его к объекту типа Y, а затем сохранять. Для сохранения я использую репозиторий для объекта (org.springframework.data.repository.PagingAndSortingRepository, если это имеет значение)

В этой конкретной таблице DBASE мне нужно создать одну сущность типа A, подключить ее к типу B, изменить объект типа B, а затем сохранить. Проблема в том, что модификация объекта типа B не сохраняется в таблице Firebird. Опять же, я использую репозиторий для сохранения объекта.

Чтобы получить тип B сущности, я использую это метод репозитория:

LsZFutelsz findOneByLsTLako(LsTLako lsTLako); 

Я предположил, что, возможно, если бы я сохранить этот тип B объект с собственным хранилищем, был бы модифицируется в базе данных правильно. Это не помогло.

Скажите, пожалуйста, если необходима дополнительная информация.

Здесь я скопирую измененный код (удалены некоторые записи, добавлены комментарии). LsZFutelszHavi - тип EntityClass типа A, LsZFutelsz - тип B EntityClass.

Конвертер абстрактного класса. Он наследуется для каждой таблицы 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); 
} 

Ребенок класса, который implmenets метод 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; 
} 

} 

хранилище для типа В сущности

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

Repository для объекта типа 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

Не могли бы вы сократить свой код до минимального примера, который показывает проблему? – micha

+0

@micha Я отвлекся с более насущной проблемой. Я смогу создать пример кода завтра – LaczkoUr

ответ

0

Код работает. Поле всегда является значением по умолчанию.

После тестирования с помощью простых методов другой объект также был сохранен в базе данных. Затем я помещаю точку останова в исходный код, который только разрывается, если новое значение для объекта отличается от значения по умолчанию. Программа конвертировала все, не нарушая точки останова.

Итак, я посмотрел, какую базу данных я конвертирую, и посмотрим, что содержимое ar. К моему удивлению, всегда было нулевое значение по умолчанию.

Это неловко. Я был так уверен, я что-то неправильно понял и неправильно закодировал.

Смежные вопросы