【发布时间】:2021-10-28 15:03:30
【问题描述】:
我有以下设置:
- Micronaut 3.x
- Java 15
我正在尝试更新的实体:
@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");
}
}
我试图将其子实体作为上述实体的一部分保留:
@Getter
@Setter
@Entity
@Table(name = "single_answer")
public class SingleAnswer extends Answer {
@OneToOne private AnswerOption choice;
}
所有实体都继承自这个:
@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;
...
}
基本答案类:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Answer extends BaseEntity {
@Column(nullable = false)
private Boolean correct;
}
以下行被执行:
@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;
}
}
预期行为:
SingleAnswer 实例被持久化,它的 FK 保存在问题的answer_id 列中。
实际行为:
SingleAnswer 实例被保留,但其 FK 未保存在问题的 answer_id 列中。它们没有以任何方式连接,因此孤立删除似乎也不起作用。
在检查了hibernate的日志后,我可以看到它只执行insert而不执行update的问题。
另一个观察结果是,当我删除刷新时,孤儿删除确实有效 - SingleAnswer 不会持续存在,尽管 FK 情况仍未解决。
orderedQuestion.answer(answer);
orderedQuestionRepository.save(orderedQuestion);
我看不出这个非常基本的设置有什么问题,任何帮助将不胜感激。
【问题讨论】:
-
我相信答案的父类很重要:它的 id 是如何初始化的?客户端还是生成?如果生成,使用什么策略?
-
@Lesiak 查看编辑
-
在这种情况下,我唯一不清楚的是问题和答案是否都插入到相同的事务方法中,或者答案是否添加到现有问题中。在第二种情况下,问题是否在保存时进行管理? (我无法重现它,在每种情况下我都会收到有关问题的更新,正如预期的那样)
-
@Lesiak 这是一个现有的问题和一个新的答案。我还有一个不同的
OderedQuestion子类-MultiChoiceQuestion,它有一个集合(One2Many)而不是单个字段。它通过相同的方法,除了问题中的#answer方法将答案添加到集合中,而不仅仅是分配。一切都适用于多重。 (见编辑中的完整方法)
标签: java hibernate one-to-one micronaut micronaut-data