java - JPA 延迟加载和泛型

标签 java hibernate generics jpa lazy-loading

我有一个域模型,其中包含一些泛型,我试图将其放入 JPA 中。我的示例是事件领域,其中您有诸如音乐会之类的事件和诸如 ConcertTickets 之类的门票。

事件:

@Entity
@Inheritance
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING, name="s_discriminator")
public abstract class Event {
...
}

音乐会:

@Entity
@Inheritance
@DiscriminatorValue("Concert")
public class Concert extends Event {
...
}

门票:

@Entity
@Inheritance
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING, name="s_discriminator")
public abstract class Ticket<E extends Event> {

  ...

  @ManyToOne(targetEntity=Event.class)
  private E event;

  public E getEvent() {
    return event;
  }
}

音乐会门票:

@Entity
@Inheritance
@DiscriminatorValue("Concert")
public class ConcertTicket extends Ticket<Concert> {
    ...
}

服务:

ConcertTicket ticket = dao.findTicket(id);
Concert concert = ticket.getConcert();

这行得通。 targetEntity 是必需的,否则我会收到以下错误:

Property Ticket.event has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type

到目前为止,我的模型没有遇到任何问题。但是我发现我的表现并不好。解决方案是将票证和事件之间的关系变成延迟加载:

  @ManyToOne(targetEntity=Event.class, fetch=FetchType.LAZY)
  private E event;

现在问题开始了。当我调用上面发布的服务时,出现以下异常:

java.lang.ClassCastException: Event_$$_jvst610_48 cannot be cast to Concert

在运行时,泛型一无所知。因此,当 JPA 实现(Hibernate)创建一个“事件”实例时,没有可用信息表明它实际上是一个“音乐会”。因此创建了“Event”的子类,而不是“Concert”的子类。

有没有人能解决这个问题?我知道有 2 个明显的解决方案:a) 避免泛型 b) 使用预先加载。我希望找到一个可以同时保留两者的解决方案。

最佳答案

有同样的问题,用 @Proxy(lazy=false) 注释父类(super class)就可以了。您可以尝试以下方法,但不确定它是否会挽救您的目的。

@Proxy(lazy=false)
public abstract class Event {
 ...
}

关于java - JPA 延迟加载和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43330983/

相关文章:

java - 简单的乒乓球游戏;无法让桨在屏幕上移动

java - ShareIt 如何在 PC 上运行?

java - 有没有类可以诊断java类中调用的方法?

java - 如何在HQL中比较时间戳和日期?

c# - 在运行时将对象转换为泛型类型

java - 在 Canvas 上画一条线,旁边再画一条虚线

hibernate - Hibernate使用flushMode = AUTO查询要慢得多,直到调用clear()为止

java - hibernate + jtable + 和自动刷新

c# - Activator.CreateInstance(string) 和 Activator.CreateInstance<T>() 的区别

ios - 在 Swift 中,不能子类泛型 : class Foo<T> : T {}