一对多的延迟加载不适用于冬眠和龙目岛

时间:2019-07-16 10:03:46

标签: postgresql hibernate spring-boot lombok

一对多的延迟加载不起作用

我有以下订单实体

@Data
@Entity
@EqualsAndHashCode
@Table(name = Order.TABLE_NAME)
public class Order implements Serializable {

private static final long serialVersionUID = -7036337819884484941L;

@Column(name = OrderNames.ORDER_ID)
private String orderId;

@Column
private String name;

@JsonManagedReference
@ToString.Exclude
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<OrderItem> orderItem = new HashSet<>();

我还有另一个实体OrderItem

@Data
@Entity
@EqualsAndHashCode(callSuper = true, exclude = "order")
@Table(name = OrderItemNames.TABLE_NAME)
public class OrderItem implements Serializable {

private static final long serialVersionUID = -7036337819884484941L;

@Column(name = OrderItemNames.ORDER_ID)
private String orderId;

@Column(name = OrderItemNames.ORDER_ITEM_ID)
private String orderItemId;

@JsonBackReference
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = OrderItemNames.ORDER_FK, nullable = false)
private Order order;

这是我的资料库

@Repository
public interface OrderRepository extends JpaRepository<Order, String> {
    Order findByOrderId(String orderId);
}

这是我的ServiceImpl

@Override
public Order findByOrderId(String orderId) {
    Order order = orderRepository.findByOrderId(orderId);

    return order;
}

据我了解, 如果我在orderRepository.findByOrderId上调试,我希望它只显示Order实体(不带OrderItem),因为获取类型是惰性的

但是实际结果是渴望的,并且订单也具有orderItem实体,无论我是否渴望/懒惰地这样做。

我也遵循了https://stackoverflow.com/a/37727206/6460497,但无济于事。 我是否想念有关ToString或@EqualsAndHashCode的东西?

编辑:

我打开了SQL日志记录,它执行2个查询(选择订单表,然后选择orderItem表)。渴望加载和延迟加载都会发生这种情况。

我还尝试删除lombok @Data,并使用@Getter @Setter创建自己相等的hashCode和toString,但是即使我将其设置为惰性,它仍然会加载数据。

这是我对postgreSql的属性

spring.jpa.database=postgresql
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.default_schema=public
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.open-in-view = false

hibernate.show_sql=true
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.format_sql=true
hibernate.hbm2ddl.auto=

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=username
spring.datasource.password=password

3 个答案:

答案 0 :(得分:0)

如果配置了getOrderItems()拦截器,则在调试时调用OpenEntityManagerInView时很有可能会初始化订单。

要在spring boot项目中关闭此功能,可以在application.properties文件中使用以下选项。

spring.jpa.open-in-view=false

您可以通过启用SQL JOIN来检查是通过SELECT查询还是其他<property name="show_sql">true</property>查询来获取订单 在您的persistent.xml中或 如果使用Spring Boot,则使用以下命令。

spring.jpa.properties.hibernate.show_sql=true

您可以在this repository中看到用于测试方案的示例。

答案 1 :(得分:0)

我通过添加以下属性找到了答案

#!/bin/bash
file=test.txt

n=$(wc -l test.txt | awk '{ print $1 }' )

i=1

while IFS= read -r line

do

while [ $i -le $n ]

do

echo "======$i====$line======$n======" /* output*/

i=$((i+1))

done

done < "$file"

我还发现,因为我正在调试实体,所以它似乎确实渴望在实际工作的地方按预期进行加载(懒惰)。

spring.jpa.open-in-view = false

说我将调试点放在

@Override
public Order findByOrderId(String orderId) {
    Order order = orderRepository.findByOrderId(orderId);
    return order;
}

在这一点上,数据库只执行一个查询(对于命令),然后我查找实体 like this 那么只有休眠状态才能查询子实体。

答案 2 :(得分:0)

您可以“订购”注释

  

@Getter(AccessLevel.NONE)