【问题标题】:JPA lazy loading and GenericsJPA 延迟加载和泛型
【发布时间】:2017-04-10 18:59:50
【问题描述】:

我有一个域模型,其中包含一些泛型,我尝试将其放入 JPA 中。我的示例是事件域,其中您拥有诸如 Concerts 之类的事件,并且拥有诸如 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 具有未绑定类型且没有明确的目标实体。 解决此通用使用问题或设置明确的目标属性(例如 @OneToMany(target=) 或使用显式 @Type

到目前为止,我的模型没有问题。但我注意到我的表现并不好。解决的办法是把ticket和Event的关系变成Lazy Loading:

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

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

java.lang.ClassCastException: Event_$$_jvst610_48 无法转换为 音乐会

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

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

【问题讨论】:

  • 不要使用 instanceof 和强制转换。使用访客模式。
  • solution c):正确支持泛型的 JPA 提供者不需要 targetEntity 指定。同样,如果这些提供程序不使用“代理”而是使用字节码增强,那么它们也没有 ClassCastException。
  • 我认为问题不足以换掉 JPA 提供程序。不过我很受诱惑:-)
  • @JBNizet :我没有使用 instanceof 或强制转换。所以我不确定访问者模式对我有什么帮助。
  • @EasterBunnyBugSmasher 你有解决办法吗?

标签: java hibernate generics jpa lazy-loading


【解决方案1】:

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

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

【讨论】:

  • 有趣。但是我已经没有代码可以尝试了。
  • :-) np,可以帮助别人。
  • 然后我突然又遇到了同样的问题。尝试了您的解决方案,它成功了! ...而且我已经担心需要一些复杂的东西。
  • 现在我注意到了这个解决方案的缺点。我与这个实体的延迟加载关系突然被急切地加载了。所以我会再次删除它并想出更好的东西
猜你喜欢
  • 2014-03-06
  • 2011-12-20
  • 2011-10-02
  • 2021-02-04
  • 2011-07-27
  • 1970-01-01
  • 2022-09-29
  • 2019-04-28
  • 2016-12-21
相关资源
最近更新 更多