当前位置: 首页 > 面试题库 >

如何实现具有通用关系的多态JPA实体

贡斌
2023-03-14
问题内容

我正在尝试使用JPA 2.0创建具有通用关系的多态实体。应该有两个表,一个事件表和一个通知表。在这些表内是彼此相关的具体实体,如下所示:

Event  <---------- Notification<X extends Event>
 |                      |
LoginEvent <------ LoginNotification extends Notification<LoginEvent>

从逻辑上讲,这应该在休眠状态下是可能的,因为在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>{

...
}

使用此代码,我可以持久保存并获取任何Event,Notification,LoginEvent或NotificationEvent,但是当我尝试LoginNotification_.event在JPA
2.0元模型查询中使用该关系时,它就会崩溃。此问题解释了类似的问题。

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);

我可以通过向元模型添加新的方法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;

    ...
}

根据一些帖子,通用关系不起作用(如何为指向通用接口的指针处理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));

我认为一个不错的查询优化器应该做的简短,但是如果有人对这种方法的效率有任何见识,我将很乐意听到!



 类似资料:
  • 问题内容: 我正在尝试使用JPA 2.0创建具有通用关系的多态实体。应该有两个表,一个事件表和一个通知表。在这些表内是彼此相关的具体实体,如下所示: 从逻辑上讲,这应该在hibernate状态下是可能的,因为在SQL中是可能的: 这就是我所拥有的: 使用此代码,我可以持久保存并获取任何Event,Notification,LoginEvent或NotificationEvent,但是当我尝试在JP

  • 我有一个JPA实体(人)与其他实体(地址)有多对一的关系。在一个对象可以被系统使用之前,这个对象必须得到主管的批准。我将原始实体存储为byte[]并对“工作”实体进行更改,并将其存储在数据库中。如果这些更改不被批准,我必须恢复原始状态。因此,我将存储的原始数据从byte[]中转换出来,并使用实体管理器将其合并到数据库中。所有的工作都很好,但是如果一个新的地址实体已经添加到“工作”的人,在合并还原的

  • 问题内容: 有一个实体类“ A”。A类可能具有相同类型“ A”的子级。如果“ A”是孩子,则也应保留它的父母。 这可能吗?如果是这样,我应该如何在Entity类中映射关系?[“ A”有一个id列。] 问题答案: 是的,这是可能的。这是标准双向@ManyToOne/ @OneToMany关系的特例。之所以特别是因为关系两端的实体都是相同的。JPA 2.0规范的第2.10.2节详细介绍了一般情况。 这

  • 我使用的是JPA注释,当我在ManyToOne中看到我的实体时,joinColumn总是具有null值。 问题是,当我在字符串中发现一个charge Relations时,这些值被插入到charge Relations表中,但带有product_id的列始终为NULL。 我已经定义了所有的setter和getter。我如何才能强制这使手册插入?谢谢

  • 我有2个实体(我删除了无用的字段): 而且 这似乎符合我的情况(也是我当前的实现),但它不起作用。 我得到以下错误消息: 来自MySQL: 临时解决方案是从存储库中检索所有相应的权限(按permissionName搜索)。那么保存效果很好。逻辑上是正确的,但我希望有一个更简单的程序...

  • 对于新学生和新课程的情况,它工作得很好,但是在新课程和现有学生的情况下,我会从数据库中抛出一个唯一的约束冲突。关系类似于下面。 在持久化之前,我尝试使用entitymanager查找一个学生,如果该学生存在,则使用该实例而不是新的学生实例。这也不起作用,它仍然尝试执行插入而不是更新