【发布时间】:2019-12-01 19:22:29
【问题描述】:
请注意,我查看了类似的问题,并解释了为什么它们对我不起作用
我有一个简单的 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;
}
我的问题是,每当我调用映射的控制器以获取所有用户时,我都会得到地址以及所有相关的注释。但我希望FetchType.LAZY 能够解决这个问题。
我在 StackOverflow 上阅读了很多问题,提到杰克逊可能是这里的罪魁祸首:
我还读到 spring.jpa.open-in-view 默认值可能是罪魁祸首:
所以我尝试了以下选项:
我通过将spring.jpa.open-in-view=false 添加到我的application.properties 来禁用默认打开视图属性,这开始给我
Could not write JSON: failed to lazily initialize a collection of role error
我假设它是因为 Jackson 正在调用我延迟加载的对象上的 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());
在响应中返回与用户关联的地址。
【问题讨论】:
-
您是否考虑过序列化某种 DTO(专用于每个用例而不是单个实体)?
-
我有,但我也想找出解决这个问题的办法。如果不探索所有选项,我不想进一步发展。
-
您是在问 (1) 如何防止 Jackson 映射
User.address,或者 (2) 如何在User.adress上启用延迟加载?这些是非常不同的问题。你已经得到了两个答案,每个答案都是我列出的两个答案中的一个。请注意,延迟加载意味着在请求时加载,不 根本不加载 -
@crizzis 我在问杰克逊如何尊重延迟加载。即使我让延迟加载工作,杰克逊也不尊重它并加载关联。
标签: java hibernate spring-boot jpa jackson