当前位置:网站首页>Analysis and solution of lazyinitializationexception
Analysis and solution of lazyinitializationexception
2022-07-04 00:34:00 【Teng Qingshan】
Introduce
If FetchType.LAZY
, Then when transmitting data to the front end, there may be LazyInitializationException
abnormal , Because the session is closed in the service , therefore JSON Mapper Object
Unable to get data .
Take an example , We will use the following entities :
When executing the following code :
List<PostComment> comments = null;
EntityManager entityManager = null;
EntityTransaction transaction = null;
try {
entityManager = entityManagerFactory()
.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
comments = entityManager.createQuery(
"select pc " +
"from PostComment pc " +
"where pc.review = :review", PostComment.class)
.setParameter("review", review)
.getResultList();
transaction.commit();
} catch (Throwable e) {
if (transaction != null &&
transaction.isActive())
transaction.rollback();
throw e;
} finally {
if (entityManager != null) {
entityManager.close();
}
}
try {
for(PostComment comment : comments) {
LOGGER.info(
"The post title is '{}'",
comment.getPost().getTitle()
);
}
} catch (LazyInitializationException expected) {
assertEquals(
"could not initialize proxy - no Session",
expected.getMessage()
);
}
Hibernate Will throw out LazyInitializationException
, Because the relationship is marked :EntityManagerPostFetchType.LAZY
, In obtaining PostComment Object is not loaded in time Post, When the entity gets later Post The session has been closed .
solve
According to design 、 Performance is different from that of developers , There are two common options to solve this problem :
The simplest one is to use FetchType.EAGER, In this way, the session is still alive at the controller method , But it affects performance .
Another way is to use
FetchType.LAZY
With a mapper( Such as MapStruct) take Entity Object conversion DTO object , Then return it to controller, Therefore, if the session is closed, there will be no exception .( This method is suitable for you only want to read or hide some properties of the object from the result , If you need to modify database records, you still have to use entities Entity.)
Here is a simple example :
@RestController
@RequestMapping("/api")
public class UserResource {
@GetMapping("/users")
public Page<UserDTO> getAllUsers(Pageable pageable) {
return userService.getAllUsers(pageable);
}
}
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional(readOnly = true)
public Page<UserDTO> getAllUsers(Pageable pageable) {
return userRepository.findAll(pageable).map(UserDTO::new);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, String> {
Page<User> findAll(Pageable pageable);
}
public class UserDTO {
private Long id;
private String firstName;
private String lastName;
private String email;
private Set<String> addresses;
public UserDTO() {
// Empty constructor needed for Jackson.
}
public UserDTO(User user) {
this.id = user.getId();
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
this.email = user.getEmail();
this.addresses = user.getAddresses().stream()
.map(Address::getAddress)
.collect(Collectors.toSet());
}
// Getters, setters, equals, and hashCode
}
@Entity
@Table(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String firstName;
@Column
private String lastName;
@Column(unique = true)
private String email;
@OneToMany(mappedBy = "address", fetch = FetchType.LAZY)
private Set<Address> addresses = new HashSet<>();
// Getters, setters, equals, and hashCode
}
@Entity
@Table(name = "address")
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String address;
@ManyToOne
@JsonIgnoreProperties(value = "addesses", allowSetters = true)
private User user;
// Getters, setters, equals, and hashCode
}
You can see , When invoking the service layer getAllUsers
Method returns UserDTO
object , And in the UserDTO Object's constructor method , Called user.getAddresses()
Method , So even after session close ,dto Objects already exist address attribute , call getAddress No LazyInitializationException
Of .
From :
The best way to handle the LazyInitializationException - Vlad Mihalcea
hibernate - Difference between FetchType LAZY and EAGER in Java Persistence API? - Stack Overflow
边栏推荐
- Why use get/set instead of exposing properties
- 功能:将主函数中输入的字符串反序存放。例如:输入字符串“abcdefg”,则应输出“gfedcba”。
- Briefly understand the operation mode of developing NFT platform
- Global and Chinese market of process beer equipment 2022-2028: Research Report on technology, participants, trends, market size and share
- Stock price forecast
- From functools import reduce -- see the use of reduce function from typical examples
- BBS forum recommendation
- The difference between objects and objects
- After the Lunar New Year and a half
- Correlation analysis summary
猜你喜欢
[GNN] hard core! This paper combs the classical graph network model
NLP pre training technology development
Briefly understand the operation mode of developing NFT platform
Idea set class header comments
Pytest unit test framework: simple and easy to use parameterization and multiple operation modes
打印菱形图案
Generic
Zipper table in data warehouse (compressed storage)
Vscode regular match replace console log(.*)
ESP Arduino playing with peripherals (V) basic concept of interrupt and timer interrupt
随机推荐
Global and Chinese market of glossometer 2022-2028: Research Report on technology, participants, trends, market size and share
想请教一下,十大劵商如何开户?在线开户是安全么?
Version rollback revert don't reset better reset must be forced
For loop
Bodong medical sprint Hong Kong stocks: a 9-month loss of 200million Hillhouse and Philips are shareholders
[Mongodb] 2. Use mongodb --------- use compass
Data storage - interview questions
功能:将主函数中输入的字符串反序存放。例如:输入字符串“abcdefg”,则应输出“gfedcba”。
P1656 bombing Railway
Solution to the impact of Remote Code Execution Vulnerability of log4j2 component on December 9, 2021
Correlation analysis summary
Shell script three swordsman sed
[2021]NeRF in the Wild: Neural Radiance Fields for Unconstrained Photo Collections
A method to solve Bert long text matching
[PHP basics] session basic knowledge, application case code and attack and defense
NLP Chinese corpus project: large scale Chinese natural language processing corpus
ESP Arduino playing with peripherals (V) basic concept of interrupt and timer interrupt
On the day when 28K joined Huawei testing post, I cried: everything I have done in these five months is worth it
打印菱形图案
[GNN] hard core! This paper combs the classical graph network model