我正在尝试使用JPA 2.0创建具有通用关系的多态实体。应该有两个表,一个事件表和一个通知表。这些表中包含相互关联的具体实体,就像这样:
Event <---------- Notification<X extends Event>
| |
LoginEvent <------ LoginNotification extends Notification<LoginEvent>
从逻辑上讲,这应该在Hibernate中是可行的,就像在SQL中一样:
+----------+ +----------+
| Event | | Notif |
+----------+ +----------+
| | | Id |
| Id | <- | Evt_id |
| Type | <- | Type |
| ... | | ... |
+----------+ +----------+
这是我的代码:
@Entity
@Inheritance
public abstract class Event{
...
}
@Entity
public class LoginEvent extends Event{
...
}
@Entity
@Inheritance
public abstract class Notification<X extends Event>{
@ManyToOne(optional=false, targetEntity=Event.class)
@JoinColumn
private X event;
...
}
@Entity
public class LoginNotification extends Notification<LoginEvent>{
...
}
使用这段代码,我可以持久化并获取任何事件、通知、登录事件或通知事件,但当我尝试在我的JPA 2.0元模型查询中使用LoginNotification_.event
关系时,它会失败。 此问题解释了类似的情况。
public static volatile SingularAttribute<NotificationEntity, EventEntity> event;
在使用条件查询进行联合操作时,出现错误:
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<LoginNotification> query = cb.createQuery(LoginNotification.class);
Root<LoginNotification> root = query.from(LoginNotification.class);
// This line complains: Type mismatch: cannot convert from
// Join<LoginNotification,Event> to Join<LoginNotification,LoginEvent>
Join<LoginNotification, LoginEvent> join =
root.join(LoginNotification_.event, JoinType.INNER);
我可以通过向 LoginNotification_
元模型中添加一个新的SingularAttribute
来解决此错误,但执行时会失败:
public abstract class LoginNotification_ extends Notification_ {
// Adding this Removes Type mismatch error, but causes run-time error
public static volatile SingularAttribute<LoginNotification, LoginEvent> event;
...
}
根据一些帖子的说法,通用关系不起作用 (How to handle JPA annotations for a pointer to a generic interface),但是通过使用@ManyToOne(optional=false, targetEntity=Event.class)
注释,我们可以使它们正常工作。遗憾的是,泛型似乎破坏了JPA标准查询。有没有什么建议可以执行此查找? 我可以在我的代码中使用
LoginNotification.getEvent()
,但我不能在我的JPA元模型连接中使用LoginNotification_.event
。有没有使用泛型以完成此操作的替代方法?@Pascal Thivent - 你能回答这个问题吗?