Hibernate:@ManyToOne(fetch = FetchType.LAZY)不适用于非主键引用列

时间:2015-01-09 06:07:17

标签: java hibernate jpa lazy-loading one-to-one

我有2个表:Order [OrderId(PK), OrderShipmentCode, ...]Shipment[ShipmentId(PK), ShipmentCode, ...]

Order课程中,我声明shipment字段如下:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OrderShipmentCode", referencedColumnName = "ShipmentCode", insertable = false, updatable = false, nullable = false)
private Shipment shipment;

当我获得Order列表时,Shipment也被加载(我看到很多单独的SELECT查询)。但我希望Shipment延迟加载,而不是与Order一起提取。

对于其他表,如果引用的列是主键,则结果与预期一致(使用延迟加载)。就我而言,ShipmentCode不是Shipment表的主键,Hibernate不使用延迟加载。

你能告诉我如何实现这个目标吗?

修改 查询代码如下:

Criteria criteria = HibernateUtil.getSessionFactory().getCurrentSession().createCriteria(Order.class);
List result = criteria.list();

SQL查询是:1 Order表的SELECT语句和Shipment的一堆SELECT语句

5 个答案:

答案 0 :(得分:1)

使用shipmentCode添加到您的实体字段并设置您的关系代码,然后将其分叉

@Column(name = "shipmentCode")
private Long shipmentCode;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OrderShipmentCode", referencedColumnName = "shipmentCode", insertable = false, updatable = false, nullable = false)
private Shipment shipment;

如果您使用Lazy-init进行实体提取而没有具有相关值的fild,那么当您尝试提取惰性实体Hibernate时将找不到任何值,因为它没有相关值

答案 1 :(得分:0)

您需要指定optional = false

@OneToOne(optional = false, fetch = FetchType.LAZY)

或简单地将其转换为@ManyToOne

@ManyToOne(fetch = FetchType.LAZY)

答案 2 :(得分:0)

试试这个:

Criteria criteria = HibernateUtil.getSessionFactory()
                                 .getCurrentSession()
                                 .createCriteria(Order.class)
                                 .setFetchMode("shipment", FetchMode.LAZY);

答案 3 :(得分:0)

您可以在订单的运送字段上使用@JsonIgnore。如果您要在发货字段中使用MappedBy,则删除该字段可能会解决您的问题。

答案 4 :(得分:0)

如果您在加载时担心多个选择查询,您可以通过使用实体图来解决这个问题。请参阅以下链接了解更多详情 https://www.baeldung.com/spring-data-jpa-named-entity-graphs