Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate JPQL HQL查询操作在类层次结构之上,采用连接继承策略并应用DTO投影_Hibernate_Jpa_Hql_Jpa 2.0_Jpql - Fatal编程技术网

Hibernate JPQL HQL查询操作在类层次结构之上,采用连接继承策略并应用DTO投影

Hibernate JPQL HQL查询操作在类层次结构之上,采用连接继承策略并应用DTO投影,hibernate,jpa,hql,jpa-2.0,jpql,Hibernate,Jpa,Hql,Jpa 2.0,Jpql,假设我有以下具有联合继承策略的类层次结构: @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Notification { protected Long id; protected Long code; protected Notification() { } } @Entity @PrimaryKeyJoinColumn(name = "NO

假设我有以下具有联合继承策略的类层次结构:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Notification {

    protected Long id;
    protected Long code;

    protected Notification() {
    }
}

@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Sms extends Notification {

    private String phoneNumber;
    private String smsText;

    public Sms() {
    }
}

@Entity
@PrimaryKeyJoinColumn(name = "NOTIFICATION_ID")
public class Push extends Notification {

    private String application;
    private String pushText;
    
    public Push() {
    }
}
如何编写JPQL/HQL查询,该查询将返回
List
,其中
NotificationDetails
是:

public class NotificationDetails {

    private final String contact;
    private final String content;

    public NotificationDetails(String contact, String content) {
        this.contact = contact;
        this.content = content;
    }
}
其中,映射应如下所示:

contact - phoneNumber / application
content - smsText / pushText

您可以尝试使用以下jpql:

List results=em.createQuery(
“选择新建com.your.entities.NotificationDetails(”
+合并(s.phoneNumber,p.application)
+合并(s.smsText,p.pushText)
+“)来自通知n”
+“在s.id=n.id上左加入Sms s”
+“p.id=n.id上的左连接推送p”,
NotificationDetails.class).getResultList();
它可以工作,但生成的sql效率很低:

选择
合并(sms1.sms\u手机、push2.push\u应用程序)为col\u 0\u 0,
合并(sms1\uU.sms\u文本,push2\uU.push\u文本)为列1\u 0\u
从TEST_SCHEMA.TST_通知通知0_
左外连接(
测试\u SCHEMA.TST\u SMS sms1\u
内部连接测试\u SCHEMA.TST\u通知sms1\u 1_
在sms1_u.sms_not_id=sms1_1_u.not_id上
)打开(sms1_u.sms_not_id=notification0_u.not_id)
左外连接(
测试\u SCHEMA.TST\u推送2\u
内部连接测试\u SCHEMA.TST\u通知push2\u 1\u
在push2上。PUSHU not\U id=push2\U 1\U not\U id
)on(push2\u.PUSHU not\u id=通知0\u.not\u id)

如果性能在这里很重要,我想最好使用本机查询并将其(例如通过
@SqlResultSetMapping
)映射到
NotificationDetails
dto。

Hibernate支持一种称为隐式子类型属性解析的查询,因此您可以使用如下查询:

List<NotificationDetails> results = em.createQuery(
   "select new com.your.entities.NotificationDetails(coalesce(n.phoneNumber, n.application),  coalesce(n.smsText, n.pushText)) from Notification n ",
   NotificationDetails.class
).getResultList();
List results=em.createQuery(
“从通知n中选择新的com.your.entities.NotificationDetails(coalesce(n.phoneNumber,n.application)、coalesce(n.smsText,n.pushText))”,
NotificationDetails.class
).getResultList();

您测试过吗?实体
Notification
没有phoneNumber、application、smsText、pushText属性,并且没有显式转换到
Sms
Push
它们不可用。我过去已经多次这样做了,所以是的,这是有效的。