Hi,
I have the following DB schema:
which I’ve tried to model in Hibernate this way (irrelevant parts left out):
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ProblematicQuery extends AbstractVersionable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "tenant_id", nullable = false)
private TenantEntity tenant;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumns(value = {
@JoinColumn(name = "tenant_id", referencedColumnName = "tenant_id", insertable = false, updatable = false, nullable = false),
@JoinColumn(name = "query", referencedColumnName = "query", insertable = false, updatable = false, nullable = false),
}, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private Judgment judgment;
@Entity
@AllArgsConstructor
public class Judgment extends AbstractAuditingEntity {
@OneToOne(mappedBy = "judgment")
private ProblematicQuery problematicQuery;
Note that ProblematicQuery is the owner and I need set insertable = false, updatable = false in the join columns in order to prevent multiple column mapping errors. However, in my business logic I’d like to do something like this:
@Transactional
public Optional<JudgmentDTO> updateJudgment(long problematicQueryId, JudgmentDTO judgmentDTO) {
return problematicQueryRepository.findById(problematicQueryId).map(pq -> {
var judgment = pq.getJudgment();
if (judgment != null) {
judgment.setApproved(judgmentDTO.approved());
}
else {
// This is the problem!
judgment = judgmentRepository.save(new Judgment(null, pq.getQuery(), judgmentDTO.approved(), pq, pq.getTenant(), null));
pq.setJudgment(judgment);
}
return judgmentMapper.toDTO(judgment);
});
}
Please note the problem: Even though in a transaction, I need to save the judgment via repository. Even worse,I do get the following warning HHH000502: The [judgment] property of the [io.searchhub.domain.ProblematicQuery] entity was modified, but it won't be updated because the property is immutable.
I do get why this is logged, but I noticed that I need to call the setter so that the Hibernate Cache is not out of sync.
Is there a better way in Hibernate to model my relation? Basically, I need the judgment independent from the ID of a ProblematicQuery as I will regularly flush the problematic query table and re-index it, and I want to keep judgments for the same query if existing. I know that I can circumvent the problem in my business logic by loading the judgment instead of the problematic query directly, but that not what I want.
Help appreciated, thanks.