请注意,我已经看过类似的问题,并且我已经解释了为什么它们对我不起作用
我有一个简单的 Spring boot JPA-Hibernate 应用程序,在用户和地址之间具有一对一的映射。 (请注意,一对多映射没有这个问题)
用户实体
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column
private String name;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private Address address;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<Note> notes;
}
地址实体
@Entity
@Table(name = "addresses")
public class Address implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column
private String street;
@Column
private String city;
@JsonIgnore
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
注释实体
@Entity
@Table(name = "notes")
public class Note implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column
private String date;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
}
我的问题是,每当我调用映射的 Controller 来获取所有用户时,我都会获取地址以及与之相关的所有注释。但我希望 FetchType.LAZY 能够解决这个问题。
我在 StackOverflow 上读到了很多问题,提到 jackson 可能是这里的罪魁祸首:
我还读到 spring.jpa.open-in-view 默认值可能是罪魁祸首:
所以我尝试了以下选项:
我通过将 spring.jpa.open-in-view=false
添加到我的 application.properties
来禁用默认在 View 中打开属性,这开始给我
Could not write JSON: failed to lazily initialize a collection of role error
我假设这是因为 jackson 正在调用我的延迟加载对象上的 setter/getter ,所以我按照另一篇文章中的说明添加了以下内容,以便 jackson 单独保留延迟加载的集合:
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.9.9</version>
</dependency>
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter converter : converters) {
if (converter instanceof org.springframework.http.converter.json.MappingJackson2HttpMessageConverter) {
ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
mapper.registerModule(new Hibernate5Module());
}
}
}
}
上面的解决方案修复了一对多映射的问题,但响应中仍然具有关联的地址。
我不知道我能在这里做什么。默认登陆页面上的用户实体不需要任何地址详细信息,因此我不想将其加载到登陆页面上。单击记录时,它会导航到另一个页面,这就是我希望在响应中返回所有延迟加载对象的地方。
我已经尝试了网上能找到的所有方法,但到目前为止仍然没有效果。我真的很感激一些帮助。
正如一位用户提到的,它可能与 SO 上的另一个问题重复: Suggested Possible duplicate 我想提一下,我通过禁用 spring.jpa.open-in-view 属性但添加
来实现延迟加载mapper.registerModule(new Hibernate5Module());
在响应中返回与用户关联的地址。
最佳答案
它的工作方式与 JPA 规范相同:-
引用以下网址 https://javaee.github.io/javaee-spec/javadocs/javax/persistence/FetchType.html
LAZY 获取策略只是一个提示(正如 javadoc 所说,可以延迟获取数据).. 不是强制操作。
Eager 是强制性的(正如 javadoc 所说,必须急切地获取数据)。
关于java - Spring boot JPA - 延迟加载不适用于一对一映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57169361/