Alex Pavlov
Alex Pavlov

Reputation: 581

REST API request using Hibernate relationships

Rest Controller:

@PostMapping("transaction")
public ResponseEntity<Transaction> init(@RequestBody Transaction transactionInput) {
    Transaction transaction = transactionRepository.save(transactionInput);
    return new ResponseEntity<>(transaction, HttpStatus.OK);
}

Transaction Entity:

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@DynamicInsert
@DynamicUpdate
@Table(name = "transaction")
public class Transaction {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name="currency_id")
    private Currency currency;

Currency Entity:

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@DynamicInsert
@DynamicUpdate
@Table(name = "currency")
public class Currency {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Length(max = 3)
    private String sign;

    @Length(max = 30)
    private String name;

Request:

curl -X POST \
  http://localhost:4000/transaction-service/transaction \
  -H 'content-type: application/json' \
  -d '{
  "currency_id": 1
}'

And it obviously currency is null and I got this error:

could not execute statement; SQL [n/a]; constraint [currency_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Is there a way to automatically mapping when I sending request with

"currency" = {"name" = "USD"}

Or how should I send this request?

Upvotes: 0

Views: 466

Answers (1)

Vlasec
Vlasec

Reputation: 5546

You cannot insert Transaction before Currency is inserted. The way you do it, it seems you are trying to insert a Transaction with its optional=false column currency_id set to null.

If you store the Currency entity first, then it should work. I am not sure if there is any good way to make such a "cascade insert" thing.

Also, this is not a good @OneToOne entity design - there is no constraint that ensures it is really one to one. CurrencyId should either be a primary key or have some unique constraint to ensure it is one to one. There is no apparent meaning of Transaction class from the snippet you posted, either.

Upvotes: 1

Related Questions