org.hibernate.LazyInitializationException:无法延迟初始化角色集合:FQPropretyName,无法初始化代理 - 无会话
Posted
技术标签:
【中文标题】org.hibernate.LazyInitializationException:无法延迟初始化角色集合:FQPropretyName,无法初始化代理 - 无会话【英文标题】:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: FQPropretyName, could not initialize proxy - no Session 【发布时间】:2018-02-25 20:16:26 【问题描述】:我正在尝试使用 SpringBoot、SpringDataJpa 的多对一双向关联以及使用 SpringBootTest 的单元测试。但是,测试失败,堆栈跟踪如下所示。但是我无法找到原因。任何指针都会有所帮助
ManyToOne 双向关联的 Spring Boot JUnit 测试失败。
@Test
public void testFindByRegionIdEquals()
Region region = regionService.findByRegionIdEquals(1L);
Region expectedRegion = new Region(1L, "Europe");
assertThat(region).isNotNull().isEqualTo(expectedRegion);
assertThat(region.getCountries()).isNotEmpty().doesNotContainNull().size().isEqualTo(8);
异常堆栈跟踪
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: zikzakjack.domain.Region.countries, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:587)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:204)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:148)
at org.hibernate.collection.internal.PersistentSet.isEmpty(PersistentSet.java:149)
at org.assertj.core.util.IterableUtil.isNullOrEmpty(IterableUtil.java:35)
at org.assertj.core.internal.Iterables.assertNotEmpty(Iterables.java:152)
at org.assertj.core.api.AbstractIterableAssert.isNotEmpty(AbstractIterableAssert.java:145)
at zikzakjack.service.RegionServiceTests.testFindByRegionIdEquals(RegionServiceTests.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
拥有实体 ManyToOne
@Data
@Entity
@Table(name = "COUNTRIES")
public class Country implements Serializable, Comparable<Country>
private static final long serialVersionUID = 1L;
@Id
@Column(name = "COUNTRY_ID")
private String countryId;
@Column(name = "COUNTRY_NAME")
private String countryName;
@ManyToOne
@JoinColumn(name = "REGION_ID")
private Region region;
public Country()
public Country(String countryId, String countryName, Region region)
super();
this.countryId = countryId;
this.countryName = countryName;
this.region = region;
*非拥有实体 OneToMany 与 mappedBy *
@Data
@Entity
@Table(name = "REGIONS")
public class Region implements Serializable, Comparable<Region>
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "REGION_ID")
private Long regionId;
@Column(name = "REGION_NAME")
private String regionName;
@OneToMany(mappedBy = "region", fetch = FetchType.LAZY)
private Set<Country> countries = new HashSet<Country>();
public Region()
public Region(Long regionId, String regionName)
this.regionId = regionId;
this.regionName = regionName;
public Region(String regionName)
this.regionName = regionName;
public void addCountry(Country country)
countries.add(country);
country.setRegion(this);
【问题讨论】:
【参考方案1】:嗯,我从这篇帖子https://***.com/a/38690930/5266568找到了答案
在 application.properties 中添加下面的配置解决了这个问题:
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
另一个对我有用的解决方案,但请注意,我仍然需要进一步了解它是如何真正解决问题的
@Transactional 确保该测试方法中的所有方法调用都发生在同一边界内。
@Test
@Transactional
public void testFindByRegionIdEquals()
Region region = regionService.findByRegionIdEquals(1L);
Region expectedRegion = new Region(1L, "Europe");
assertThat(region).isNotNull().isEqualTo(expectedRegion);
assertThat(region.getCountries()).isNotEmpty().doesNotContainNull().size().isEqualTo(8);
【讨论】:
enable_lazy_load_no_trans
是反模式导致 n+1 问题不要使用它。
是的@YouYou。见vladmihalcea.com/…
谢谢!我测试中的@Transactional 注释解决了我的问题(和你一样的问题)以上是关于org.hibernate.LazyInitializationException:无法延迟初始化角色集合:FQPropretyName,无法初始化代理 - 无会话的主要内容,如果未能解决你的问题,请参考以下文章