log*_*gan 15 java hibernate metamodel jpa-2.0
我正在尝试使用JPA 2.0来创建具有泛型关系的多态实体.应该有两个表,一个事件表和一个通知表.在这些表中是彼此相关的具体实体,如下所示:
Event <---------- Notification<X extends Event>
| |
LoginEvent <------ LoginNotification extends Notification<LoginEvent>
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,这应该可以在hibernate中实现,因为它可以在SQL中实现:
+----------+ +----------+
| Event | | Notif |
+----------+ +----------+
| | | Id |
| Id | <- | Evt_id |
| Type | <- | Type |
| ... | | ... |
+----------+ +----------+
Run Code Online (Sandbox Code Playgroud)
这就是我所拥有的:
@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>{
...
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,我可以持久化并获取任何Event,Notification,LoginEvent或NotificationEvent,但当我尝试LoginNotification_.event在JPA 2.0元模型查询中使用该关系时,它就会失败.这个问题解释了类似的东西
public static volatile SingularAttribute<NotificationEntity, EventEntity> event;
Run Code Online (Sandbox Code Playgroud)
当我尝试在条件查询中进行连接时,出现错误:
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);
Run Code Online (Sandbox Code Playgroud)
我可以解决这个错误,通过添加新SingularAttribute的LoginNotification_元模型,但这种失败在执行:
public abstract class LoginNotification_ extends Notification_ {
// Adding this Removes Type mismatch error, but causes run-time error
public static volatile SingularAttribute<LoginNotification, LoginEvent> event;
...
}
Run Code Online (Sandbox Code Playgroud)
根据一些帖子,泛型关系不起作用(如何处理指向泛型接口的指针的JPA注释),但是通过使用@ManyToOne(optional=false, targetEntity=Event.class)注释,我们可以让它们表现出来.不幸的是,泛型似乎打破了JPA标准查询.
有关如何执行此查找的建议吗?我可以LoginNotification.getEvent()在我的代码中使用,但我不能LoginNotification_.event在我的JPA元模型连接中使用.使用泛型来实现这一目标的替代方法是什么?
@Pascal Thivent - 你能回答这个问题吗?
对此的一个解决方案是避免使用"join"函数并执行完全交叉连接:
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<LoginNotification> query = cb.createQuery(LoginNotification.class);
Root<LoginNotification> notfRoot = query.from(LoginNotification.class);
Root<LoginEvent> eventRoot = query.from(LoginEvent.class);
...
query.where(cb.equals(notfRoot.get(Notification_.event), eventRoot.get(Event_.id)), ...(other criteria));
Run Code Online (Sandbox Code Playgroud)
我认为一个体面的查询优化器应该对此做一些简短的工作,但如果有人对这种方法的效率有任何见解,我会热衷于听到它!
| 归档时间: |
|
| 查看次数: |
10179 次 |
| 最近记录: |