EntityManager ThreadLocal z JPA w JSE

Opracowuję prosty projekt „Book Store” przy użyciu Struts 1.3 + JPA (z Hibernate jako dostawcą trwałości). Nie mogę przełączyć się na Spring lub inne bardziej zaawansowane środowisko programistyczne (np. Jboss) i nie mogę używać żadnej techniki specyficznej dla Hibernate (np.Session klasa).

Biorąc pod uwagę fakt, że jestem w środowisku JSE, muszę jawnie zarządzać całym cyklem życia EntityManager.

TheBook jednostka jest zdefiniowana następująco:

@Entity
public class Book {

@Id private String isbn;
private String title;
private Date publishDate;

    // Getters and Setters
}

Zdefiniowałem trzyAction klasy, które są odpowiedzialne, odpowiednio, za pobieranie wszystkich instancji książki, pobieranie pojedynczej instancji książki przez ISBN i łączenie odłączonej książki z DB.

W celu zwiększenia separacji obaw między kodem logiki biznesowej a kodem dostępu do danych wprowadziłem prostyBookDAO obiekt, który jest odpowiedzialny za wykonywanie operacji CRUD. W idealnym przypadku wszystkie wywołania związane z dostępem do danych powinny być delegowane do warstwy trwałości. Na przykładListBookAction jest zdefiniowany następująco:

public class ListBookAction extends Action {

    private BookDAO dao = new BookDAO();

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        // Retrieve all the books
        List<Book> books = dao.findAll();

        // Save the result set
        request.setAttribute("books", books);

        // Forward to the view
        return mapping.findForward("booklist");
    }

}

Obiekt BookDAO musi uzyskać dostęp doEntityManager przykład w celu wykonania jakiejkolwiek operacji. Jeśli się uwzględniEntityManger nie jest bezpieczny dla wątków, wprowadziłem nazwę klasy pomocniczejBookUnitSession który enkapsuluje EntityManager w ciąguThreadLocal zmienna:

public class BookUnitSession {

    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("BookStoreUnit");
    private static final ThreadLocal<EntityManager> tl = new ThreadLocal<EntityManager>();

    public static EntityManager getEntityManager() {
        EntityManager em = tl.get();

        if (em == null) {
            em = emf.createEntityManager();
            tl.set(em);
        }
        return em;
    }

}

Wszystko wydaje się działać, ale nadal mam pewne obawy. Mianowicie:

Czy jest to najlepsze rozwiązanie? jaka jest najlepsza praktyka w tym przypadku?Nadal muszę dokładnie zamknąć zarówno EntityManager, jak i EntityManagerFactory. Jak mogę to zrobić?

Dzięki

questionAnswers(2)

yourAnswerToTheQuestion