2

我正在開發一個使用Spring Boot和Hibernate JPA的Web服務應用程序。我有一個分層架構,它由請求控制器層,業務邏輯(服務)層和數據訪問(存儲庫)層組成。領域模型/實體是:春季服務層沒有關閉Hibernate jpa實體管理器

@Entity 
public class User { 

    @Id 
    @GeneratedValue 
    private Long id; 
    @OneToMany 
    @JoinColumn(name = "userId") 
    private List<Address> addresses; 
} 

@Entity 
public class Address { 

    @Id 
    @GeneratedValue 
    private Long id; 
} 

正如你所看到的,我有一個用戶實體與懶加載策略地址許多單向關係。在存儲庫層中,我有一個簡單的用戶存儲庫,它擴展了Spring數據JpaRepository。

public interface UserRepository extends JpaRepository<User, Long> { 
} 

在服務層,沒有業務邏輯的簡單用戶獲取方法。

@Service 
public class UserServiceImpl implements UserService { 

    @Autowired 
    private UserRepository userRepository; 

    @Override 
    public User getUser(Long id) { 
     return this.userRepository.findOne(id); 
    } 
} 

在控制器簡單的用戶資源控制器方法。

@RestController 
@RequestMapping(value = "/api/v1/users") 
public class UserResource { 

    @Autowired 
    private UserService userService; 

    @RequestMapping(value = "/{userId}", method = RequestMethod.GET) 
    public User getUser(@PathVariable Long userId) { 
     return this.userService.getUser(userId); 
    } 
} 

我的問題是,當我嘗試從服務層獲取用戶時,我也會得到用戶的地址,雖然它被聲明爲延遲初始化。我也沒有啓用交易。除了在控制器中使用JSON序列化之外,我沒有調用任何getter方法。 Hibernate JPA實體管理器仍將在控制器層中打開。但我無法想象如何。不是我應該得到懶惰的初始化異常嗎?

+0

你真的在字段上映射註解而不是getters?據我所知,如果字段訪問屬性(getters),Hibernate允許您獲取惰性關聯的ID,而不需要獲取對象。查看[this](https://developer.jboss.org/wiki/HibernateFAQ-TipsAndTricks#jive_content_id_How_can_I_retrieve_the_identifier_of_an_associated_object_without_fetching_the_association)瞭解詳情。 –

+0

我確實有getter和setter。我刪除它只是爲了顯示實體之間的關係,並保持簡短。謝謝 –

+0

你還有在地址類中的@Id批註getter而不是字段?因爲這可以解釋你看到的行爲 –

回答

4

Spring Boot註冊一個OpenEntityManagerInViewInterceptor(檢查JpaBaseConfiguration類),它確保實體管理器對於完整的請求是開放的,這意味着可以在將實體序列化爲JSON時解析延遲集合。

如果要禁用該行爲,請將配置spring.jpa.open-in-view=false添加到您的application.properties中。

+0

完全合作......感謝dunni和bohuslav的幫助......我總是認爲官方文件是完美的參考資料,但在實踐中無法應用這些紀律。謝謝兄弟 –

相關問題