2014-09-19 2 views
0

Привет, мои коллеги-программисты!Общий класс управления объектами JPA

Я работаю над назначением школы, которое в основном включает в себя создание HTML через сервлеты - и связь с базой данных (postgreSQL) через JPA. Все работает, как задумано, однако, я создал класс, чтобы управлять своими сущности через EntityMangerFactory и т.д.:

package no.hib.dat104.database; 

import java.util.List; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.EntityTransaction; 
import javax.persistence.Query; 
import javax.persistence.RollbackException; 

public class Management<T> { 

EntityManagerFactory factory; 
EntityManager em; 
EntityTransaction transaction; 

public Management(EntityManagerFactory factory) { 
    this.factory = factory; 
    em = factory.createEntityManager(); 
    transaction = em.getTransaction(); 
} 

public List<Message> retrieveMessages() { 
    transaction.begin(); 
    TypedQuery q = 
      em.createQuery("SELECT m FROM Mesage m", Message.class); 
    List<Message> res = q.getResultList(); 
    transaction.commit(); 
    return res; 
} 

public void update(T entity) { 
    transaction.begin(); 
    em.refresh(entity); 
    transaction.commit(); 
} 

public void add(T entity) { 
    transaction.begin(); 
    em.persist(entity); 
    transaction.commit(); 
} 

//reference point ONE) 
public Person retrievePerson(Integer id) { 
    transaction.begin(); 
    TypedQuery q = 
      em.createQuery("SELECT p FROM Person p WHERE p.id = :var"); 
    q.setParameter("var", id); 
    List<Person> result = q.getResultList(); 
    transaction.commit(); 
    return result.size() > 0 ? result.get(0) : null; 
} 

//reference point TWO) 
//public Person retrievePerson(Integer id) { 
// transaction.begin(); 
// TypedQuery q = 
//   em.createQuery("SELECT p FROM Person p WHERE p.id = :var"); 
// q.setParameter("var", id); 
// Person result = q.getSingleResult(); 
// transaction.commit(); 
// return result; 
//} 

public Person retrievePerson(String name) { 
    transaction.begin(); 
    TypedQuery q = 
      em.createQuery("SELECT p FROM Person p WHERE p.name = :var"); 
    q.setParameter("var", name); 
    List<Person> result = q.getResultList(); 
    transaction.commit(); 
    return result.size() > 0 ? result.get(0) : null; 
} 
} 

И я нахожу этот класс не очень эффективным. Мой сервлет инициализирует две ссылки на Management.java:

EntityManagerFactory factory = Persistence.createEnetityMangagerFactory("openjpa"); 
Management<Message> maM = new Management<Message>(factory); 
Management<Person> maP = new Management<Person>(factory); 

Итак:
Вопрос 1): Есть ли способ восстановить фактор это (код Management.java), чтобы сделать его более эффективный родовым ?
Вопрос 2): Я прокомментировал две контрольные точки, ONE) и TWO) в классе. TWO) throws NullPointerException NoResultException, если ничего не найдено. Какой из них наиболее эффективен? Или есть лучшее решение?

Любые ответы или комментарии есть «много-LY» оценил - извините мой английский :)

+1

Думаю, вам стоит прочитать о шаблоне DAO (который более или менее то, что вы делаете). Кроме того, хотя код может использовать некоторый рефакторинг, я не знаю, что вы подразумеваете под «эффективным» - запросы к базе данных, подобные этому, не будут быстрее. – Deltharis

+0

Возможно, вы правы, спасибо. Я имел в виду нечто вроде «более общего» - трудно сформулировать себя. – Superdids

+0

Контрольная точка TWO) не может выбрасывать 'NullPointerException'. Он должен бросить 'javax.persistence.NoResultException', когда нет строки, которая соответствует указанным критериям. – Arek

ответ

0

http://java.dzone.com/articles/jpa-implementation-patterns - которые должны получить через Generic процесс создания DAO. Важные моменты:

  • Использование EJB или Spring может позволить вам избавиться от этой уродливой фабрики, проходящей в конструкторе, и может позаботиться о обработке транзакций.
  • вам нужен общий класс, который послужит основой для всех DAO конкретного класса. Это, вероятно, будет включать в себя общие добавления, удаления, findById, обновление и findAll
  • для каждого объекта (сообщение, личность) вы создаете подкласс общего класса. Он позаботится о параметризации суперкласса, и именно там вы поместите все сущностные методы.

Что касается Вопроса 2 - как @Ajan указывает TWO), то будет выдано другое исключение, но тем не менее исключение. Bah, если вы перейдете к использованию PersistenceContext, то исключение при выходе из DAO может быть обернуто другим исключением, которое делает обработку ошибок раздражающей. Как правило, большой палец я бы предположил, что исключение не должно быть исключено из методов DAO, и даже если поймать в методе обработки исключений все еще медленно. Я использую ваш возврат ONE).

+0

Большое спасибо! – Superdids

Смежные вопросы