Представьте, что у меня есть класс Debtor
. С Hibernate, я буду определять класс так:Как сопоставить абстрактный класс или интерфейс в Hibernate HQL?
@Entity
@Table(name = "T_DEBTOR")
public class Debtor {
@Id
@Column(name = "ID_DEBTOR")
private String idDebtor;
...
Мой DAO будет тогда выглядит следующим образом:
public class DebtorDaoImpl implements DebtorDao {
@PersistenceContext
private EntityManager em;
@SuppressWarnings("unchecked")
public List<Debtor> findAllDebtors() {
Query q = em.createQuery("select d from Debtor d");
return (List<Debtor>) q.getResultList();
}
Это хорошо работает. Тем не менее, я в конфигурации, где мне нужно получить доступ к различным схемам (как указано here). Конечно, в каждой схеме таблица, в которой размещен список должников, имеет одно и то же имя. В дополнение к этому у них может не быть такой же структуры. Вот почему у меня есть x differents Debtor
класс (где x - это число схем, которыми я управляю).
В случае, когда у меня есть две схемы различий, у меня будет два разных класса Debtor
: DebtorOne
и DebtorTwo
. Как я хочу, чтобы облегчить мои разработки, я создал интерфейс (или абстрактный класс, это не меняет мою проблему здесь), которая реализуется как DebtorOne
и DebtorTwo
:
public interface Debtor {
String getIdDebtor();
}
и:
@Entity
@Table(name = "T_DEBTOR_ONE")
public class DebtorOne implements Debtor {
@Id
@Column(name = "ID_DEBTOR")
private String idDebtor;
...
Если я позволяю мой DAO, как это, я получаю следующее сообщение об ошибке из спящего режима:
Caused by: org.hibernate.hql.ast.QuerySyntaxException: Debtor is not mapped [select d from Debtor d]
Если я изменить DAO, чтобы это:
public List<Debtor> findAllDebtors() {
Query q = em.createQuery("select d from DebtorOne d");
return (List<Debtor>) q.getResultList();
}
, то это работает, но это относится только к DebtorOne
схеме ...
Одно решение, которое я вижу, чтобы определить именованный запрос на DebtorOne
и DebtorTwo
классов и называем это именованный запрос от моего DAO. В других словах:
@Entity
@Table(name = "T_DEBTOR_ONE")
@NamedNativeQueries({ @NamedNativeQuery(name = "findAllDebtors", query = "select d from DebtorOne d") })
public class DebtorOne implements Debtor {
и в DAO:
@SuppressWarnings("unchecked")
public List<Debtor> findAllDebtors() {
Query q = em.createNamedQuery("findAllDebtors");
return (List<Debtor>) q.getResultList();
}
Я не пробовал, но я думаю, что это будет работать ...
EDIT Я просто попробовал, это будет работать ... за исключением того, что NamedQuery
должно быть названо по-разному для DebtorOne
и DebtorTwo
...
Однако мне интересно, есть ли способ решить мою проблему без использования последнего решения?
Редактировать относительно первого ответа, который наводит на мысль использовать @MappedSuperclass
. Эта аннотация кажется идеальным решением для меня, но я думаю, что я что-то забыл, так как я все еще получаю ту же ошибку.
Основной Debtor
:
@MappedSuperclass
public class Debtor {
@Id
@Column(name = "IDDEBTOR")
protected String idDebtor; // With getter and setter
}
один из расширенного Debtor
класса:
@Entity
@Table(name = "DEBTOR_ONE")
public class DebtorOne extends Debtor {
...
и в моей DAO:
public List<Debtor> findAllDebtors() {
return (List<Debtor>) em.createQuery("select d from Debtor d").getResultList();
}
еще возвращая мне ошибку Caused by: org.hibernate.hql.ast.QuerySyntaxException: Debtor is not mapped [select d from Debtor d]
Что я пропустил на этот раз?