I have the following setup:
- Micronaut 3.x
- Java 15
Entity I'm trying to update:
@Setter
@Getter
@Entity
@ToString
@Table(name = "single_choice_question")
public class SingleChoiceQuestion extends OrderedQuestion {
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
private SingleAnswer answer;
@Override
public void answer(Answer answer) {
if (answer instanceof SingleAnswer single) {
this.answer = single;
}
throw new IllegalArgumentException("answer is not of SingleAnswer type");
}
}
Its child entity I'm trying to persist as part of the one above:
@Getter
@Setter
@Entity
@Table(name = "single_answer")
public class SingleAnswer extends Answer {
@OneToOne private AnswerOption choice;
}
All entities inherit from this:
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(updatable = false, nullable = false, length = 36)
@Type(type = "pkg.UuidUserType") // Maps UUID to SQL VARCHAR.
private UUID id;
@Version
@Column(nullable = false)
private Integer version;
...
}
the base answer class:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Answer extends BaseEntity {
@Column(nullable = false)
private Boolean correct;
}
The below lines are executed:
@ReadOnly
public class MyService {
@Transactional
public <A extends AnswerDto> A answer(A dto, UUID question) {
var answer = questionsMapper.toAnswer(dto);
answer.setCorrect(isCorrect(dto, question));
var orderedQuestion =
orderedQuestionRepository
.findById(question)
.orElseThrow(() -> new NotFoundException("question", question));
orderedQuestion.answer(answer, false);
orderedQuestionRepository.saveAndFlush(orderedQuestion);
return dto;
}
}
Expected behaviour:
the SingleAnswer instance is persisted, and its FK is saved in the answer_id
column of the question.
Actual behaviour:
the SingleAnswer instance is persisted, but its FK is NOT saved in the answer_id
column of the question. They are not connected in any way, so orphan removal doesn't seem to work either.
After examining hibernate's logs, I can see it only executes the insert
and does not do and update
on the question.
Another observation is when I remove flushing, orphan removal does work - SingleAnswer
doesn't persist, although the FK situation isn't resolved still.
orderedQuestion.answer(answer);
orderedQuestionRepository.save(orderedQuestion);
I can't see anything wrong with this very basic setup, any help would be appreciated.
CodePudding user response:
Include the @JoinColumn
annotation indicating the foreign key in SingleChoiceQuestion
entity:
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "answer_id")
private SingleAnswer answer;
CodePudding user response:
The issue was painfully simple, a @ReadOnly
sneaked in on a class level at some point by someone, and I didn't notice