此问题在此处已有答案:
Problem with LazyInitializationException(2个答案)
19天前关闭。
这篇文章是4天前编辑并提交审查的。
我在数据库中有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;
}
@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());
当我运行上面的代码时,一切正常。我也得到了fraud
和fraudActions
的关联,没有得到任何错误。
我的印象是,由于两个实体Fraud
和FraudActionEntity
都在急切地获取对方,所以它应该会给予一些错误,如循环获取/无限获取循环,但它没有!
为什么它能工作?什么时候会给予循环提取错误或无限提取循环错误?如果它确实出现循环提取错误,我们可以在@ManyToOne端使用lazy fetch来修复它吗,如下所示:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fraud_id")
private Fraud fraud;
1条答案
按热度按时间i7uaboj41#
更新:针对
LazyInitializationException
的一个简单而有效的解决方案是用@Transactional
注解来注解你的方法。这将在执行方法的同时创建和维护事务,从而允许你的代码对DB的惰性init对象进行必要的调用。Learn more about it here。JPA存储库方法的返回类型应该是实体对象的列表,因为结果可能不止一行(这可能是您获取
fraud
变量的空值的原因)。关于Fetch策略,您可以对该特定关联使用Eager,也可以使用other strategies。一种可能的解决方案是,在需要延迟加载的FraudAction对象列表时进行第二次查询。
此外,作为附带说明avoid using lombok data annotation,始终确保您的Entity/DTO类中有一个
NoArgsConstructor
(在您的示例中,@Data
意外添加了该变量,因为它包括@RequiredArgsConstructor
,并且您没有任何最终变量。