Spring Boot JPA Lazy Fetch 不起作用 [英] Spring Boot JPA Lazy Fetch is not working
问题描述
我有以下两个域对象 Suggestion 和 UserProfile
它们以一对多的关系相互映射.当我使用 Spring Data JPA 获取所有建议时,我会使用每个建议对象获得相应的用户对象.即使我将 fetch
设置为 FetchType.Lazy
,也会观察到这个结果.以下是我的代码:
Suggestion.java
@Entity@Table(name="建议")@JsonIgnoreProperties({"suggestionLikes"})公开课建议{公共建议(){//TODO 自动生成的构造函数存根}@ID@GeneratedValue(策略=GenerationType.IDENTITY)@Column(name="suggestion_id")私人整数建议Id;@Column(名称=说明")私人字符串描述;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name="suggestion_by")私人 UserProfile 用户;//getter 和 setter}
UserProfile.java
@Entity@Table(name = "user_master")@JsonIgnoreProperties({"suggestions", "suggestionLikes"})公共类 UserProfile 实现了 Serializable {/****/私有静态最终长serialVersionUID = 7400472171878370L;公共用户配置文件(){}@ID@NotNull@Column(name = "用户名", 长度 = 55)私人字符串用户名;@NotNull@Column(name = "密码")私人字符串密码;@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)私人设置<建议>建议;//getter 和 setter}
以下是获取记录的服务:
@Override@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)公开列表<建议>getAllSuggestion() {返回建议Respository.findAll();;}
建议库:
@Repository公共接口 SuggestionRespository 扩展 JpaRepository{公开列表<建议>找到所有();}
以下是 Application 类:
@EnableTransactionManagement@SpringBootApplication公共类 AngularSpringbootApplication {公共静态无效主(字符串 [] args){SpringApplication.run(AngularSpringbootApplication.class, args);}}
application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/plan_tripspring.datasource.username=rootspring.datasource.password=rootspring.jpa.properties.hibernate.dialect =org.hibernate.dialect.MySQL5InnoDBDialectspring.jpa.hibernate.ddl-auto = 更新spring.jackson.serialization.fail-on-empty-beans=false
执行 getAllSuggestions()
时收到的响应:
]
预期响应:
<代码>[{建议ID":2,"description": "德语!","createdBy": "vinit2","createdDate": "2018-06-19T10:38:32.000+0000",修改者":vinit2",修改日期":2018-06-19T10:38:32.000+0000"},{建议ID":1,"description": "瓦赛!","createdBy": "vinit1","createdDate": "2018-06-19T10:37:38.000+0000",修改者":vinit1",修改日期":2018-06-19T10:37:38.000+0000"}]
当我将 FetchType
声明为 Lazy
时,当我在 Suggestion 上执行 findAll()
时,我不应该获取 User 对象(以 JSON 格式)实体.
我在这里遗漏了什么?
您可以使用@JsonManagedReference &@JsonBackReference 以防止 jakson 调用代理.以下代码可能对您有所帮助.
@JsonBackReference@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)私人设置<建议>建议;@JsonManagedReference@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "suggestion_by")私人 UserProfile 用户;
添加以下依赖项,根据你的休眠更改版本
<依赖><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-hibernate5</artifactId></依赖>
最后添加一个新的配置
@Configuration公共类 JacksonConfig {@豆角,扁豆公共 Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {返回新的 Jackson2ObjectMapperBuilderCustomizer() {@覆盖公共无效定制(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder){jacksonObjectMapperBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);jacksonObjectMapperBuilder.modules(new Hibernate5Module());}};}}
I have following two domain objects Suggestion and UserProfile
They are mapped with each other in one to many relationship. When I fetch all suggestions using Spring Data JPA, I get corresponding user object with each suggestion objects. This result is observed even when I have set fetch
as FetchType.Lazy
. Following is my code:
Suggestion.java
@Entity
@Table(name="suggestion")
@JsonIgnoreProperties({"suggestionLikes"})
public class Suggestion {
public Suggestion() {
// TODO Auto-generated constructor stub
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="suggestion_id")
private Integer suggestionId;
@Column(name="description")
private String description;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="suggestion_by")
private UserProfile user;
//getters and setters
}
UserProfile.java
@Entity
@Table(name = "user_master")
@JsonIgnoreProperties({"suggestions", "suggestionLikes"})
public class UserProfile implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7400472171878370L;
public UserProfile() {
}
@Id
@NotNull
@Column(name = "username", length = 55)
private String userName;
@NotNull
@Column(name = "password")
private String password;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Suggestion> suggestions;
//getters and setters
}
Following is the service which fetches the records:
@Override
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public List<Suggestion> getAllSuggestion() {
return suggestionRespository.findAll();;
}
SuggestionRepository:
@Repository
public interface SuggestionRespository extends JpaRepository<Suggestion,
Integer> {
public List<Suggestion> findAll();
}
Following is the Application class:
@EnableTransactionManagement
@SpringBootApplication
public class AngularSpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(AngularSpringbootApplication.class, args);
}
}
application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/plan_trip
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
spring.jackson.serialization.fail-on-empty-beans=false
Response received when getAllSuggestions()
is executed:
[
{
"suggestionId": 2,
"description": "Germanyi!",
"createdBy": "vinit2",
"createdDate": "2018-06-19T10:38:32.000+0000",
"modifiedBy": "vinit2",
"modifiedDate": "2018-06-19T10:38:32.000+0000",
"user": {
"userName": "vinit2",
"password":
"$2a$10$.hP0sQWpl6qqDKiNTkiu0OciQeHRFnkEbEWcDvnv1HY4QCi2tKo.2",
"firstName": "Vinit2",
"lastName": "Divekar2",
"emailAddress": "vinit@gmail.com",
"createdBy": null,
"modifedBy": null,
"createdDate": "2018-06-04",
"modifiedDate": "2018-06-04",
"isActive": "1",
"handler": {},
"hibernateLazyInitializer": {}
}
},
{
"suggestionId": 1,
"description": "Vasai!",
"createdBy": "vinit1",
"createdDate": "2018-06-19T10:37:38.000+0000",
"modifiedBy": "vinit1",
"modifiedDate": "2018-06-19T10:37:38.000+0000",
"user": {
"userName": "vinit1",
"password": "$2a$10$D0RMSTWu03Jw7wC1/zqFxOOjb0Do24o/4mq2PhDhRUyBrs8bdGvUG",
"firstName": "Vinit1",
"lastName": "Divekar1",
"emailAddress": "vinit@gmail.com",
"createdBy": null,
"modifedBy": null,
"createdDate": "2018-06-04",
"modifiedDate": "2018-06-04",
"isActive": "1",
"handler": {},
"hibernateLazyInitializer": {}
}
}
]
Expected response:
[{
"suggestionId": 2,
"description": "Germanyi!",
"createdBy": "vinit2",
"createdDate": "2018-06-19T10:38:32.000+0000",
"modifiedBy": "vinit2",
"modifiedDate": "2018-06-19T10:38:32.000+0000"
},
{
"suggestionId": 1,
"description": "Vasai!",
"createdBy": "vinit1",
"createdDate": "2018-06-19T10:37:38.000+0000",
"modifiedBy": "vinit1",
"modifiedDate": "2018-06-19T10:37:38.000+0000"
}
]
When I have declared FetchType
as Lazy
, I should not get User objects (in JSON) when I execute findAll()
on Suggestion entity.
What am I missing here?
You can use @JsonManagedReference & @JsonBackReference to prevent proxy call by jakson. Following code may help you.
@JsonBackReference
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Suggestion> suggestions;
@JsonManagedReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "suggestion_by")
private UserProfile user;
Add the following dependency, change version according to your hibernate
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>
and finally add a new config
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
jacksonObjectMapperBuilder.modules(new Hibernate5Module());
}
};
}
}
这篇关于Spring Boot JPA Lazy Fetch 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!