2009-06-05 2 views
1

그래서 Spring MVC + Hibernate를 사용하는 간단한 웹 애플리케이션이 있고 OpenSessionInViewFilter를 사용하고 있습니다. 나는 최근 UI를 Flex 나 GWT와 같은 것으로 대체하려고 생각 해왔다.RIA에서 지연로드는 언제 문제가됩니까?

처음에는 새로운 프런트 엔드에서 서비스 레이어에 도달 할 수 있다는 점에서 쉽지 않을 것이라고 생각했습니다. 그러나 이것을 조금 더 생각해 보면, 나는 게으른 로딩을 둘러싼 문제들에 대해 약간 긴장되어 있습니다. 뷰에서 열린 세션을 사용하고 있기 때문에 전통적인 웹 프런트 엔드를 사용하면 문제가 없습니다 ... 뷰를로드 할 때 필요한 모든 것이 뷰가 생성 될 때로드됩니다.

그래서 고객을 돌려 줄 수있는 방법이 있고 고객에게 많은 주소록이 있고 주소록에 여러 주소가있는 경우를 가정 해 봅니다. 내 새 "RIA"컨트롤러에서 getCustomer()를 호출하면 고객이 생기 겠지만 고객의 연락처 콜렉션은 프록시 또는 null이 될 것입니다.

미리 채워진 DTO를 반환하는 것 위에 새로운 레이어를 만들 수는 있지만 복잡해 질 것 같습니다.

어떤 조언이 필요합니까?

답변

2

귀하는 이것이 RIA에 문제가 있음을 확신합니다. OpenSessionInViewFilter를 사용하는 경우 데이터는 null을 반환하지 않습니다. 오히려 시리얼 라이저는 전체 객체 그래프를 걷고 거대한 양의 데이터를 되돌려 보냅니다. 이것은 심각한 성능 문제를 일으킬 것입니다.

별도의 DTO 레이어를 사용하면 serializer가 생성 한 객체 만 볼 수 있다는 점에서 많은 제어가 가능합니다. 당신은 그들이 게으른 프록시를 포함하지 않도록 할 수 있습니다. 이것은 유감스럽게도 엔티티와 DTO 사이에 매핑 코드를 작성하는 데 약간의 지루함을 가져다 주지만 원하는 모든 작업을 완벽하게 제어 할 수 있습니다.

또 다른 접근법은 직렬화를 위해 개체 그래프를 준비하는 serializer 바로 앞에 레이어를 도입하는 것입니다. 과거 프로젝트에서 사용한 한 가지 접근 방법은 전체 객체 그래프를 걷고 지연 프록시를 @Id 속성 집합 만있는 Entity의 새 인스턴스로 대체하는 서비스 계층에 기능을 도입하는 것이 었습니다. 그래프가 나중에 저장되면, 이것은 @ManyToOne 관계가 부주의하게 0이되지 않도록합니다. getter를 호출하거나 Hibernate.initialize()를 사용하여 강제로 데이터를 초기화 할 수 있습니다. 이것은 Hibernate에서 @OneToMany 또는 @ManyToMany 관계의 계단식 저장을 도입 할 때 더 복잡해집니다.

최근에이 문제를 해결하기 위해 설계된 Gilead라는 solutin을 발견했습니다.

http://www.graniteds.org/confluence/display/DOC/4.+Lazy+Initialization

하나의 문제 I : 나는 또한 화강암 DS는 조수 프레임 워크의 일부로서이 문제에 대한 해결책을 가지고 있다고 생각

http://noon.gilead.free.fr/gilead/

: 그것은 위에서 설명한 것과 유사한 방법을 사용 누군가가 해결했다고 생각하지 마십시오. 실제로 서버에서 RIA로 데이터를로드하는 게으름니다.나는 확실히 할 수 있다고 생각하지만 여기에는 몇 가지 보안 문제가있다. 첫 번째 장소에서 데이터를 실제로로드 할 수있는 권한을 가진 사용자가 데이터를 게으른로드하려고 시도했는지 확인하기 위해 강력한 보안 검사가 필요합니다.

+0

고마워요! dpHibernate에 대한 경험이 있습니까? 나는 그것이 나를 위해이 문제를 해결할지도 모른다라고 생각한다. 그러나 나는 확실하지 않다 (즉, 내가 Flex를 사용하기로 결정한다면). – Boden

+0

설명서를 검토했지만 dpHibernate로 코딩하지 않았습니다. 내가 가진 큰 걱정 중 하나는 보안 문제를 해결하지 못했지만 뭔가를 놓친 것일 수도 있다는 것입니다. –

+0

보안 문제에 대해 자세히 설명해 주시겠습니까? – Boden

0

프리젠 테이션 레이어에 고객 연락처가 필요한 경우 데이터 레이어가 제공합니다. lazy loading의 목적은 데이터를 생략하는 것이 아니라 컴퓨터 프로그래밍에서 필요한 시점까지 객체 초기화를 지연시키는 데 사용됩니다.

걱정할 필요가 없습니다.

+0

흠, 그건 나에게 이상하지 않습니다. 반환하는 객체는 직렬화 될 것이므로 포함 된 모든 객체가로드되기 전에로드되어야합니다. 따라서 메소드 getCustomer()를 호출하고 고객이 게으른로드 된 연락처 모음을 가지고있는 경우, Customer 객체는 직렬화시 연락처의 유효한 콜렉션을 포함하지 않습니다. 클라이언트가 getCustomer(). getContacts()를 수행하려고하면 아무 것도 얻지 않습니다. – Boden

+0

사실 내 우려 사항은 거꾸로 실현 될 수있는 것처럼 보입니다. 모든 것이 직렬화 (적어도 스프링의 블레이즈를 사용하여)에로드 될 것입니다 ... 서로 다른 문제를 함께 제시합니다. 다음을보십시오 : http://www.infoaccelerator.net/blog/post.cfm/bypassing-hibernate-s-lazy-loading-in-blazeds-with-spring – Boden

관련 문제