1

I know, that this question has been asked many times, but my case is different (e.g. How to save parent and child in one shot (JPA & Hibernate))

I have DTOs:

@Data
public class ExchangeRatesTableDto {
    private ExchangeRatesTableType table;
    private String no;
    private LocalDate tradingDate;
    private LocalDate effectiveDate;
    private List<ExchangeRateDto> rates;
}

@Data
public class ExchangeRateDto {
    private String currency;
    private String code;
    private Double mid;
    private Double bid;
    private Double ask;
}

And Entities:

@Data
@Entity
@Table(schema = DatabaseNames.SCHEMA_NBP)
public class ExchangeRatesTable {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @Enumerated(EnumType.ORDINAL)
    private ExchangeRatesTableType tableType;

    private String no;
    private LocalDate tradingDate;
    private LocalDate effectiveDate;

    @OneToMany(mappedBy = "exchangeRatesTable", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<ExchangeRate> exchangeRates;
}
@Data
@Entity
@Table(schema = DatabaseNames.SCHEMA_NBP)
public class ExchangeRate {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
    @JoinColumn(foreignKey = @ForeignKey(name = "FK_exchange_rates_table"))
    private ExchangeRatesTable exchangeRatesTable;

    private String currency;
    private String code;
    private Double mid;
    private Double bid;
    private Double ask;
}

I have two repositories too:

public interface ExchangeRatesTableRepository extends JpaRepository<ExchangeRatesTable, UUID> {
}

public interface ExchangeRateRepository extends JpaRepository<ExchangeRate, UUID> {
}

And in controller I have this code:

ModelMapper modelMapper = new ModelMapper();
ExchangeRatesTableDto table = exchangeRatesService.getTable(exchangeRatesTableType);
ExchangeRatesTable exchangeRatesTable = modelMapper.map(table, ExchangeRatesTable.class);
exchangeRatesTableRepository.save(exchangeRatesTable);

exchangeRatesService returns ExchangeRatesTableDto with childs. ModelMapper returns: ExchangeRatesTable object

But save method is not working:

Hibernate: /* insert model.ExchangeRatesTable */ insert into nbp.exchange_rates_table (effective_date, no, table_type, trading_date, id) values (?, ?, ?, ?, ?)
Hibernate: /* insert model.ExchangeRate */ insert into nbp.exchange_rate (ask, bid, code, currency, exchange_rates_table_id, mid, id) values (?, ?, ?, ?, ?, ?, ?)
2021-04-14 14:27:42.889  WARN 11404 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 23502
2021-04-14 14:27:42.889 ERROR 11404 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: null value in column "exchange_rates_table_id" of relation "exchange_rate" violates not-null constraint
  Szczegóły: Failing row contains (f2a461e5-80ce-4837-aab9-a87919c978f8, null, null, BRL, real (Brazylia), 0.6658, null).
could not execute statement; SQL [n/a]; constraint [exchange_rates_table_id" of relation "exchange_rate]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Nolias
  • 101
  • 1
  • 10

1 Answers1

1

you have to manually set each and every ExchangeRate object with ExchangeRatesTable object, as you have ExchangeRatesTable setter method. then it will not be empty and get save in the DB as well.

Parent parent = new Parent();
Child child1 = new Child();
child1.setParent(parent);
parent.setChildren(Arrays.asList(child1));
jpa.save(parent);

in your code you can iterate ExchangeRateList and set ExchangeRatesTable obj to all elements.

krishna thota
  • 182
  • 1
  • 3
  • 8
  • I forget about it. I added method to the `ExchangeRatesTable` class: ``` lang-java public void setExchangeRates(Set exchangeRates) { exchangeRates.forEach(exchangeRate -> exchangeRate.setExchangeRatesTable(this)); this.exchangeRates = exchangeRates; } ``` and replaced `@Data` with `@Getter` and `@Setter`, and it works. – Nolias Apr 15 '21 at 06:35