2016-11-16 2 views
2

Могу ли я использовать дженерики и JPA вместе?Использование generics и jpa Методы EntityManager

Я пытаюсь сохранить объекты четырех классов в своем db. Вот мой класс PersistService:

public class PersistService<T> { 
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("fileUploadProject"); 

public static EntityManager getEntityManager() { 
    return emf.createEntityManager(); 
} 

// Write Client to Database 
public static <T> void persist(T obj) { 
    EntityManager em = getEntityManager(); 
    EntityTransaction et = em.getTransaction(); 
    et.begin(); 
    em.persist(obj); 
    et.commit(); 
    em.close(); 
} 
} 

Но тогда у меня возникает проблема с удалением объекта. У меня есть следующий метод в классе PersistService в дополнение к вышесказанному:

// Remove an object from the Database if they exist 
public static <T> void remove(Long id) { 
    EntityManager em = getEntityManager(); 
    EntityTransaction et = em.getTransaction(); 
    <T> obj = em.find(<T>.class, id); 
} 

Последняя строка дает мне ошибку времени компиляции. Я пробовал <T>.classTClass<T> и T.class также, но он по-прежнему дает мне ошибку времени компиляции. Из-за этой ошибки, просто узнав о Type Erasure? Как решить эту проблему?

+0

Вы должны попытаться сделать GenericDao и сделать дочерние классы продлить его – BrunoDM

+0

Вы никогда не хотите, чтобы операции управляются в ваших 'методов PersistService'. Вы хотите управлять границами транзакций на основе логических фрагментов бизнес-логики.Как правило, вы выполняете несколько операций с базой данных, которые вы хотите или все преуспеете, или все сбой - в противном случае ваша система останется в непоследовательном состоянии, с которой сложно выполнить код и с которым сложно восстановить. – Rob

+0

Вы не можете получить тип класса во время компиляции. вы потратите достаточно времени и ресурсов на поиски. –

ответ

2

Вы начали использовать хороший образец. Следующим шагом будет создание подкласса PersistService для каждого из ваших типов сущностей. Я также упомянул, что в конечном итоге вы, вероятно, захотите иметь общий базовый класс или интерфейс для каждого из ваших объектов. Например, я назову его Entity. Этот базовый класс (если это класс, а не интерфейс) может быть абстрактным и может определять общие методы для всех ваших объектов.

public interface Entity { 
    long getId(); 
} 

Вы можете использовать методы, определенные Entity в вашей реализации PersistService (которые вы можете найти под рукой, как вы добавите более общую сущность, связанные с бизнесом-логику в этой базовой услуге или в другом месте в коде).

Ваше предприятие A выглядит

public class A extends Entity { 
} 

Ваш PersistService становится

public abstract class PersistService<T extends Entity> { 
    // Your common methods (persist, remove, etc.). 
    public abstract Class<T> getEntityClass(); 
} 

Ваш объектные конкретные услуги выглядеть следующим образом

public class APersistService extends PersistService<A> { 
    public Class<A> getEntityClass() { 
     return A.class; 
    } 
} 

затем используется метод getEntityClass() при реализации PersistService.remove().

В то время как подклассы, специфичные для сущности, решают проблему получения конкретного объекта класса перед стиранием типа, вы обнаружите, что в конечном итоге вы хотите, чтобы подкласс также поддерживал запросы, специфичные для сущности.

0

Возможно, у меня есть ответ, который вы ищете, ну, чтобы иметь общий тип во время компиляции, это не так просто. Поскольку java не позволяет вам делать это напрямую.

У меня есть взломать себя, вы можете попробовать что-то подобное?

Обязательно соблюдайте свои исключения.

static <T> Class getGenericType(T t){ 
    return getType(t); 
} 
static Class<?> getType(Object o){ 
    return o.getClass(); 
} 
Смежные вопросы