在同一事务中查找实体时,多对一关系始终为空
Posted
技术标签:
【中文标题】在同一事务中查找实体时,多对一关系始终为空【英文标题】:ManyToOne relationship is always null when finding entity in the same transaction 【发布时间】:2021-05-07 01:01:07 【问题描述】:我有一个与 ModeratorEntity 具有多对一关系的 ConversationEntity
@Entity
@Table(name="CONVERSATIONS")
public class ConversationEntity
@Id
private Integer id;
private Integer moderatorId;
@ManyToOne
@JoinColumn(name="moderatorId", insertable=false, updatable=false)
private ModeratorEntity moderator;
@Entity
@Table(name="MODERATORS")
public class ModeratorEntity
@Id
private Integer id;
private Integer name;
还有一个带有事务方法的服务类,它首先保存 ModeratorEntity,然后保存之前创建的具有 moderatorId 的 ConversationEntity
@Transactional
public void doStuff(Moderator moderator, Integer conversationId)
Integer moderatorId = moderatorService.save(moderator);
Integer conversationId = conversationService.save(conversationId, moderatorId);
//do other stuff
Conversation conversation = conversationService.findById(conversationId);
当我试图通过同一事务中的 id 查找 ConversationEntity 时,下面几行,我得到了设置了字段 moderatorId 但 ModeratorEntity 对象 = null 的 ConversationEntity。
如果我在事务之外执行此操作,我将正确设置 ModeratorEntity 对象。
我尝试在 ModeratorRepository 和 ConversationRepository 中使用 saveAndFlush 并在 ManyToOne 关系中设置 FetchType.EAGER 但它们都不起作用
【问题讨论】:
你认为FK字段应该是insertable=false, updatable=false
这样没有问题。问题是为什么如果我在同一个事务中发现存储库返回一个非空 id 但一个空相关实体
@AlejandroCuervo 也许你应该使用name="moderatorId"
而不是name="moderator_id"
?
与数据库字段的映射是正确的。我想应该是交易出了点问题
【参考方案1】:
有很多关于类似问题的问题。例如@Transactional in bidirectional relation with Spring Data returns null 和Hibernate: comparing current & previous record。
只要您在单个事务中,您将始终获得相同的实例,并且实际上不会从数据库中加载任何数据。而且因为(至少看起来)你从来没有设置对ModeratorEntity
的引用,所以它保持null
。
一旦您处于新事务中,就会访问数据库并且 JPA 会填充一个新实例,现在包括一个 ModeratorEntity
引用。
因此,可能的修复方法是:
让moderatorService.save
返回一个实体并将其设置在Conversation
中,而不是一个id。您不妨放弃moderatorId
。这是使用 JPA 做事的惯用方式。
在单独的事务中执行查询。弹簧TransactionTemplate
可能会派上用场。虽然这确实有效,但它会导致 JPA 内部渗透到您的应用程序中,我建议您避免这样做。
【讨论】:
在保存之前在 ConversationEntity 中设置 moderatorEntity 对我有用!!!谢谢以上是关于在同一事务中查找实体时,多对一关系始终为空的主要内容,如果未能解决你的问题,请参考以下文章
如何防止 EntityType 在与同一实体(父)的多对一关系中显示当前对象?