【问题标题】:How to map an abstract class or interface in Hibernate HQL?如何在 Hibernate HQL 中映射抽象类或接口?
【发布时间】:2010-12-12 13:45:13
【问题描述】:

假设我有一个Debtor 课程。使用 Hibernate,我将这样定义类:

@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 个不同 Debtor 类(其中 x 是我操作的模式的数量)。

如果我有两个不同的模式,我将有两个不同的Debtor 类:DebtorOneDebtorTwo。 由于我想简化我的开发,我创建了一个由DebtorOneDebtorTwo 实现的接口(或抽象类,它不会改变我的问题):

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 保持原样,我会从 Hibernate 收到以下错误:

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 架构...

我看到的一个解决方案是在 DebtorOneDebtorTwo 类上定义一个命名查询,并从我的 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();
}

我还没有尝试过,但我认为它会起作用......

编辑我刚试过,这会起作用...除了NamedQuery 必须为DebtorOneDebtorTwo 命名不同...

但是,我想知道是否有一种方法可以在不使用后一种解决方案的情况下解决我的问题?


编辑关于第一个答案,建议使用@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]

这次我错过了什么?

【问题讨论】:

    标签: java hibernate hql


    【解决方案1】:

    我认为这对于接口是不可能的,而只能使用一个公共抽象基类,它将用 @MappedSuperclass 注释(有关详细信息,请参阅 Hibernate 文档)

    【讨论】:

      【解决方案2】:

      我认为要使其工作,您要么必须将Debtor 表实际映射到表,要么使用按类策略(联合子类)的表。 @MappedSuperClass 似乎只实现了一种非常基本的机制来复制属性并且无法工作,因为您无法查询超类的实例。

      我从链接中得知,您已经有一些东西可以避免在休眠会话中为DebtorOne 的架构映射DebtorTwo(否则查询Debtor 会提取所有记录,包括来自@ 987654327@ 不存在的表)。在这种情况下,请按照example from the documentation 为任一情况映射子类。

      【讨论】:

        猜你喜欢
        • 2011-05-15
        • 1970-01-01
        • 1970-01-01
        • 2014-10-13
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 2012-11-06
        • 1970-01-01
        相关资源
        最近更新 更多