[英]Lazy loading not working in spring data jpa one to many bi directional mapping
[英]Spring boot JPA - Lazy loading is not working for One to One mapping
請注意,我看過類似的問題,並解釋了為什么它們對我不起作用
我有一個簡單的 Spring 啟動 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
我假設它是因為傑克遜在我懶惰加載的對象上調用吸氣劑,所以我按照另一篇文章中的說明添加了以下內容,讓傑克遜獨自離開懶惰加載的集合:
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 上的另一個問題重復: 建議可能重復我想提一下,我通過禁用 spring.jpa.open-in-view 屬性來使延遲加載工作,但添加
mapper.registerModule(new Hibernate5Module());
在響應中帶回與用戶關聯的地址。
您可以查看Jackson Serialization Views 。
我已經查看了您嘗試過的 Hibernate5 模塊,它有一些有趣的功能......但沒有人應該為您解決這個問題。
順便說一下,我通常通過不返回實體作為響應而是返回 DTO 來解決這個問題。
它的工作方式與 JPA 規范一樣:-
請參閱以下 URL https://javaee.github.io/javaee-spec/javadocs/javax/persistence/FetchType.html
LAZY fetching 策略只是一個提示(因為 javadoc 說可以延遲獲取數據)......不是強制性操作。
急切是強制性的(因為 javadoc 說必須急切地獲取數據)。
問題是jackson在寫JSON時觸發了初始化,所以不要寫當前字段(地址)。 但是你不應該使用@jsonIgnore
所以在其他地方你可以返回一個Eager
obj。
您可以使用@jsonView
批注,該批注可以在不同的請求中為同一個 obj 提供不同的 JSON。 你可以看看這個例子:
創建視圖類:
public class ViewFetchType {
static class lazy{ }
static class Eager extends lazy{ }
}
注釋您的實體
@Entity
public class User {
@Id
@JsonView(ViewFetchType.Lazy.class)
private String id;
@JsonView(ViewFetchType.Eager.class)
@OneToOne( fetch = FetchType.LAZY)
private Address address ;
}
在控制器中指定FetchType
類:
public class UserController {
private final UserRepository userRepository;
@Autowired
UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@RequestMapping("get-user-details")
@JsonView(ViewFetchType.Eager.class)
public @ResponseBody Optional<User> get(@PathVariable String email) {
return userRepository.findByEmail(email);
{
@RequestMapping("get-all-users")
@JsonView(ViewFetchType.Lazy.class)
public @ResponseBody List<User> getUsers() {
return userRepository.findAll();
}
}
這是我從...的想法中得到的答案... https://stackoverflow.com/a/49207551/10162200
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.