2011-08-11 1 views
4

나는 Hibernate, Spring 및 Wicket을 기반으로하는 웹 애플리케이션을 개발 중이다.Wicket, Spring, Hibernate 기반 웹 응용 프로그램에서 LoadableDetachableModel을 올바르게 사용하는 방법은 무엇입니까?

지금까지는 비즈니스 개체와 지속성 계층을 구현했습니다. 트랜잭션은 Spring 프레임 워크의 트랜잭션 인터셉터에 의해 관리된다. 따라서 DAO 클래스의 각 메소드는 트랜잭션에 캡슐화됩니다. 단위 테스트와 함께이를 구현하는 것은 간단했습니다.

이제 웹 의존성 주입을 위해 Spring을 사용하는 웹 응용 프로그램 파트로 이동합니다. Wicket 프레임 워크의 @SpringBean 주석과 함께 Wicket 구성 요소에 DAO를 주입합니다. 그러나 Wicket을 처음 접했을 때 비즈니스 객체에 맞는 모델을 사용할 때 Wicket 구성 요소를 전달할 때 약간의 문제가 생겼습니다.

LoadableDetachableModel을 시도했지만 몇 가지 문제가 있습니다. 새 페이지를 만들거나 페이지의 입력 매개 변수에 따라 기존 비즈니스 개체를 편집 할 수있는 페이지가 하나 있습니다. 매개 변수에 ID가 있으면 해당 Business Object를 데이터베이스에서로드해야합니다. 매개 변수가 없으면 새 비즈니스 오브젝트를 작성해야합니다. 그 부분은 편집되어야하는 객체 였지만, 새로운 객체가 만들어 져야 할 때 웹 폼을 채우고 save를 누르면 NullPointerException이 발생합니다. 일부 디버깅 후 오버로드 된 load() 메서드는 데이터베이스에 개체 형식을로드 할 수 없으므로 LoadableDetachableModel이 비즈니스 개체의 인스턴스를 반환 할 수 없다는 것을 알았습니다. 아직 저장되지 않았으므로 ID가 없습니다.

이제이 문제를 해결하는 방법을 궁금합니다. LoadableDetachableModel이 올바른 선택입니까? 양식을 두 개의 상호 의존적 인 양식으로 분리하고 각 양식이 다른 모델을 사용하는 것이 좋습니다. 따라서 편집 페이지/양식 만 LoadableDetachableModel을 사용합니까?

답변

2

이고르 반 베르크 (Igor Vaynberg)의 the Wicket In Action blog의 관련 문제에 대한 좋은 설명이 있습니다. LoadableDetachableModel를 사용하지만 더 완벽하게 제어 할 수있는 AbstractEntityModel를 구현 하지에 의해 기본적으로

이 문제와 해당 페이지 거래의 마지막 비트. 다음과 같이

+0

도 참조 새로운 http://wicket.apache.org/guide/guide/modelsforms.html 이미있는 링크 LoadableDetachableModel' –

+0

이없는이 https를 사용 존재'사용 개찰구 6.x에서 용 : // 대신 ci.apache.org/projects/wicket/guide/7.x/guide/modelsforms.html –

0

Wicket 6.x Reference Documentation > 11 Wicket models and forms > 11.6 Detachable models는 설명 :

지금 LoadableDetachableModel의 가능한 사용의 예로서, 우리는 JPA를 통해 관리 엔티티와 함께 ​​작동하도록 설계 모델을 구축 할 것입니다

. 다음 코드를 이해하려면 JPA에 대한 기본 지식이 필요합니다. 이 표준의 세부 사항에 대해서는 다루지 않겠습니다.

다음 모델은 예제 용도로만 제공되며 실제 환경에서 사용하기위한 것입니다 ( ). 트랜잭션 관리와 같은 중요한 측면은 고려하지 않으므로 코드를 사용하기 전에 다시 작성해야합니다. JPA 엔티티를 관리하는 JPA 인터페이스 javax.persistence.EntityManagerFactory 의 구현이 모델에 의해 처리되어야하는 엔티티 :

public class JpaLoadableModel<T> extends LoadableDetachableModel<T> { 

    private EntityManagerFactory entityManagerFactory; 
    private Class<T> entityClass; 
    private Serializable identifier; 
    private List<Object> constructorParams; 

    public JpaLoadableModel(EntityManagerFactory entityManagerFactory, T entity) { 
     super(); 

     PersistenceUnitUtil util = entityManagerFactory.getPersistenceUnitUtil(); 

     this.entityManagerFactory = entityManagerFactory; 
     this.entityClass = (Class<T>) entity.getClass(); 
     this.identifier = (Serializable) util.getIdentifier(entity); 

     setObject(entity); 
    } 

    @Override protected T load() { 
     T entity = null; 

     if(identifier != null) { 
      EntityManager entityManager = entityManagerFactory.createEntityManager(); 
      entity = entityManager.find(entityClass, identifier); 
     } 
     return entity; 
    } 

    @Override protected void onDetach() { 
     super.onDetach(); 

     T entity = getObject(); 
     PersistenceUnitUtil persistenceUtil = entityManagerFactory.getPersistenceUnitUtil(); 

     if(entity == null) return; 

     identifier = (Serializable) persistenceUtil.getIdentifier(entity); 
    } 
} 

모델의 생성자 입력으로 두 개의 매개 변수. 생성자 내부에서 모델은 엔티티 클래스와 해당 ID를 저장합니다. 엔티티가 아직 보존되지 않은 경우 인 경우 null이 될 수 있습니다.이 두 정보는 나중에 엔터티를 검색하는 데 필요한 이며로드 메서드 에서 사용됩니다.

onDetach은 분리 전에 이 발생하기 전에 엔티티 ID를 업데이트해야합니다. id는 엔티티가 처음 지속될 때 변경 될 수 있습니다 (JPA 은 새 ID를 생성하고이를 엔티티에 할당합니다). 이 모델은 분리되기 전에 엔터티 개체에 발생한 변경 사항을 저장하는 데 책임지지 않습니다. 이 변경 사항을 풀고 싶지 않은 경우에는 단계가 분리되기 전에 명시 적으로 엔티티를 유지해야합니다.

이 예제의 모델은 EntityManagerFactory에 대한 참조를 보유하므로 사용중인 구현은 Serializable이어야합니다.

관련 문제