Spring Rest API未展示嵌套列表结果问题求助
multies List Not Returning in Spring REST API Hey there! I’ve run into this exact lazy loading serialization issue with Spring and Hibernate before—let’s break down why your multies list isn’t showing up in the API response and walk through actionable fixes.
Why This Happens
Your @OneToMany relationship uses FetchType.LAZY, which means Hibernate won’t load the multies list until you explicitly access it. But by the time Spring tries to serialize the Geometry object to JSON, the Hibernate session is typically already closed. This either triggers a LazyInitializationException or the serializer just skips the unloaded list entirely (which sounds like what’s happening here).
Solutions to Try
1. Switch to Eager Loading (Quick but Not Always Ideal)
You can change the fetch type to EAGER so Hibernate loads the multies list immediately when fetching a Geometry:
@OneToMany(mappedBy="geometry", cascade= CascadeType.ALL, fetch=FetchType.EAGER) private List<Multi> multies = new ArrayList<Multi>();
Note: This works for small datasets, but if your multies lists are large or you don’t always need them, eager loading can hurt performance by pulling unnecessary data every time you fetch a Geometry.
2. Use DTOs (Best Practice for Control & Performance)
Create Data Transfer Objects (DTOs) to explicitly define what data you want to return, then map your entities to these DTOs in the service layer. This lets you load the multies list on demand using a JOIN FETCH query:
First, define the DTOs:
// GeometryDTO.java @Data public class GeometryDTO { private long id; private List<MultiDTO> multies; } // MultiDTO.java @Data public class MultiDTO { // Include only the fields you need from the Multi entity private long id; // Add other necessary fields (e.g., name, value) }
Then, update your repository to fetch multies alongside Geometry with a JOIN FETCH query:
public interface GeometryRepository extends JpaRepository<Geometry, Long> { @Query("SELECT g FROM Geometry g JOIN FETCH g.multies WHERE g.id = :id") Geometry findByIdWithMulties(@Param("id") long id); }
Finally, map the entity to the DTO in your service (use ModelMapper or MapStruct to simplify mapping):
@Service public class GeometryService { private final GeometryRepository geometryRepo; private final ModelMapper modelMapper; // Inject ModelMapper via Spring public GeometryDTO getGeometryWithMulties(long id) { Geometry geometry = geometryRepo.findByIdWithMulties(id); return modelMapper.map(geometry, GeometryDTO.class); } }
This approach gives you full control over what data is returned and avoids unnecessary database queries—perfect for production.
3. Use Jackson’s Hibernate Module
If you want to keep lazy loading but still serialize the list, add Jackson’s Hibernate module to handle lazy-loaded entities. Add this dependency to your pom.xml (or build.gradle):
<!-- Maven --> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate5</artifactId> </dependency>
Then configure Jackson to use the module (Spring Boot usually auto-configures this, but you can explicitly define it):
@Configuration public class JacksonConfig { @Bean public Module hibernateModule() { return new Hibernate5Module(); } }
This module will auto-load lazy collections during serialization, but ensure the Hibernate session is open (you might need to add @Transactional to your controller method, though this isn’t ideal for controllers long-term).
4. Enable Open Session In View (OSIV) (Use With Caution)
You can keep the Hibernate session open until the response is sent by enabling OSIV. Add this to your application.properties:
spring.jpa.open-in-view=true
Warning: OSIV can cause performance issues and session leaks in large applications—it’s generally considered an anti-pattern for production. Use this only as a temporary fix or for small projects.
Final Recommendation
For most production scenarios, using DTOs with JOIN FETCH queries is the best balance of performance, control, and maintainability. Avoid eager loading unless you’re certain you always need the nested list, and steer clear of OSIV unless absolutely necessary.
内容的提问来源于stack exchange,提问作者Kaci Hyou

