在同一事务中查找实体时,ManyToOne 关系始终为 null
ManyToOne relationship is always null when finding entity in the same transaction
我有一个与 ModeratorEntity 有 ManyToOne 关系的 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;
}
还有一个服务 class 具有事务性方法,首先保存 ModeratorEntity,然后保存 ConversationEntity 和之前创建的 moderatorId
@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,但其中 none 有效
类似的问题还有很多。例如 and Hibernate: comparing current & previous record.
只要您在单个事务中,您将始终获得相同的实例,并且实际上不会从数据库加载任何数据。而且因为(至少看起来)你从来没有设置对 ModeratorEntity
的引用,所以它保持 null
.
一旦您处于新事务中,就会访问数据库并且 JPA 会填充一个新实例,现在包括一个 ModeratorEntity
引用。
因此,可能的修复方法是:
让 moderatorService.save
return 实体代替 id,并将其设置在 Conversation
中。您不妨删除 moderatorId
。这是使用 JPA 做事的惯用方式。
在单独的事务中执行查询。弹簧 TransactionTemplate
可能会派上用场。虽然这确实有效,但它会导致 JPA 内部渗入您的应用程序,我建议您避免这种情况。
我有一个与 ModeratorEntity 有 ManyToOne 关系的 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;
}
还有一个服务 class 具有事务性方法,首先保存 ModeratorEntity,然后保存 ConversationEntity 和之前创建的 moderatorId
@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,但其中 none 有效
类似的问题还有很多。例如
只要您在单个事务中,您将始终获得相同的实例,并且实际上不会从数据库加载任何数据。而且因为(至少看起来)你从来没有设置对 ModeratorEntity
的引用,所以它保持 null
.
一旦您处于新事务中,就会访问数据库并且 JPA 会填充一个新实例,现在包括一个 ModeratorEntity
引用。
因此,可能的修复方法是:
让
moderatorService.save
return 实体代替 id,并将其设置在Conversation
中。您不妨删除moderatorId
。这是使用 JPA 做事的惯用方式。在单独的事务中执行查询。弹簧
TransactionTemplate
可能会派上用场。虽然这确实有效,但它会导致 JPA 内部渗入您的应用程序,我建议您避免这种情况。