How to configure Hibernate @JoinColumn on another table with foreign key reference differs from PK

81 views Asked by At

I have a main table:

@Entity
public class History {

    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "task_id")
    private Task taskId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "status", referencedColumnName = "status_code")
    private Status status;

And I have two referenced tables:

@Entity
public class Status {

    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Short id;

    @Column(name = "status_code", unique = true, nullable = false)
    private Short statusCode;
}

@Entity
public class Task {

    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column()
    private String task;
}

Then I want to save History via JpaRepository in DB in such way:

History history = new History();

Task task = new Task();
task.setId(dto.getId());
history.setTaskId(task);

Status status = new Status();
status.setStatusCode(dto.getStatus());
history.setStatus(status);

historyRepository.save(history);

So I want to save existing Task.id and Status.statusCode to History table.

During this I have no problem with Task entity, but have such error with Status entity:

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : 
ru.example.model.History.status -> ru.example.model.Status; 
nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: 
object references an unsaved transient instance - save the transient instance before flushing : 
ru.example.History.status -> ru.example.Status

So it looks like Hibernate wants me to set id for Status entity. But I have refernce foreign key not on id field, but on status_code field.

If I set id for Status entity, it works fine.

As well as if I get it from DB and then save it in History entity.

But I would like it to work in a way as Task entity, without getting it from DB. And I have only status_code, not id. Are there any ways to solve it?

1

There are 1 answers

3
ardit mete On

Why are you creating task and status classes as @Entity if you are not saving them on database? First thing you need to do is to save the status and task on database like:

Task task = new Task();
task.setId(dto.getId());
taskRepository.save(task);

Status status = new Status();
status.setStatusCode(dto.getStatus());
statusRepository.save(status);

History history = new History();
history.setTaskId(task);
history.setStatus(status);

Also use SaveAndFlush in order to get the db updated while you save History object.

historyRepository.saveAndFlush(history);