【问题标题】:Bidirectional OneToMany JPA mapping with eager fetch on both sides worked [duplicate]双向 OneToMany JPA 映射在双方都有效 [重复]
【发布时间】:2022-11-06 04:47:50
【问题描述】:

我在 DB 中有 3 个表,在 Java 应用程序中有 3 个 JPA 实体。

@Data
@Entity
public class Fraud {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "fraud_type")
    private String fraudType;

    @Column(name = "fraud_value")
    private String fraudValue;

    @OneToMany(mappedBy = "fraud", fetch = FetchType.EAGER)
    private List<FraudActionEntity> fraudActions;
    
}

@Data
@Entity
public class FraudActionEntity {

    @Id
    @Column(name = "id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "fraud_id")
    private Fraud fraud;

    @ManyToOne
    @JoinColumn(name = "action_id")
    private Action action;

    @Column(name = "enabled")
    private Boolean enabled;
}

@Data
@Entity
public class Action {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "attribute_key")
    private String attributeKey;

    @Column(name = "attribute_value")
    private String attributeValue;

}

我的用例:-

对于某种类型的欺诈,我想遍历由该类型欺诈触发的所有操作并对其采取行动。

所以我想使用下面的 JPA 查询访问Fraud:-

@Repository
public interface FraudRepository extends JpaRepository<Fraud, Integer> {

    public Fraud findByFraudTypeAndFraudValue(String fraudType, String fraudValue);

}

访问代码

    Fraud fraud = fraudRepository.findByFraudTypeAndFraudValue("Type", "Value");
    log.info(fraud.getFraudActions().get(0).getAction());  

当我上面的代码运行时,一切正常。 我也得到了fraudfraudActions 关联,没有出现任何错误。

我的印象是FraudFraudActionEntity 两个实体都在互相获取热切地所以它应该给出一些错误,比如循环获取/无限获取循环,但它没有!

为什么它起作用了?究竟什么时候会给它像循环获取错误或无限获取循环错误这样的错误? 如果它确实给出了循环获取错误,我们可以使用惰性来修复它吗? 在@ManyToOne 一侧获取,如下所示:-

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fraud_id")
    private Fraud fraud;

【问题讨论】:

  • 你能包括你得到的堆栈跟踪吗?

标签: java spring hibernate spring-data-jpa orm


【解决方案1】:

更新:针对LazyInitializationException 的一个简单且非常有效的解决方法是使用@Transactional 注释来注释您的方法。这将在方法执行时创建和维护事务,从而允许您的代码对 DB 的惰性 init 对象进行必要的调用。 Learn more about it here

您的 JPA 存储库方法的返回类型应该是实体对象的列表,因为结果可能不止一行(这可能是您获得 fraud 变量的空值的原因)。

关于 Fetch 策略,您可以在该特定关联上使用 Eager 或 other strategies。一种可能的解决方案是进行第二次查询,以防您需要延迟加载的 FraudAction 对象列表。

此外,作为旁注avoid using lombok data annotation,并始终确保您的实体/DTO 类中有NoArgsConstructor(在您的情况下,@Data 偶然添加了它,因为它包含@RequiredArgsConstructor 而您没有任何最终变量。

【讨论】:

  • 不,欺诈不是 null,欺诈.getFraudActions 返回错误。欺诈具有对象的引用。如果它已经抛出异常,我们如何进行 2bd 查询。
  • 我误解了“即使只是记录欺诈也会引发异常”这一事实。澄清一下,您的 FraudActionEntity 是否有 JpaRepository
  • 是的,我目前没有,但如果需要,我可以制作一个。
  • @tusharRawat 查看我更新的答案。快乐的黑客攻击 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 2023-03-04
相关资源
最近更新 更多