Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Sql 如何编写JPQL查询以查找在此联接中未找到的记录?_Sql_Hibernate_Jpql_Outer Join - Fatal编程技术网

Sql 如何编写JPQL查询以查找在此联接中未找到的记录?

Sql 如何编写JPQL查询以查找在此联接中未找到的记录?,sql,hibernate,jpql,outer-join,Sql,Hibernate,Jpql,Outer Join,就我个人而言,我不知道如何构造这个JPA查询 我需要查找未在给定SyncSendingConfig下传输的事务日志,按ID排序 对此进行研究,我认为在SQL中应该可以进行外部连接,其中一侧的ID为null,如下图所示: 以下是我必须处理的实体 @Entity public class SyncSendingConfig { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "i

就我个人而言,我不知道如何构造这个JPA查询

我需要查找未在给定SyncSendingConfig下传输的事务日志,按ID排序

对此进行研究,我认为在SQL中应该可以进行外部连接,其中一侧的ID为null,如下图所示:

以下是我必须处理的实体

@Entity
public class SyncSendingConfig {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "sendingConfig")
    private Set<SyncJob> sendJobs = new HashSet<>();
}

@Entity
public class SyncJob {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sending_config_id")
    private SyncSendingConfig sendingConfig;

    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(
        name = "SyncJob_TransactionLog", 
        joinColumns = { @JoinColumn(name = "sync_job_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "transaction_log_id") }
    )
    private Set<TransactionLog> transmitted = new HashSet<>();
}

@Entity
public class TransactionLog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @ManyToMany(mappedBy = "transmitted")
    private Set<SyncJob> syncJobs = new HashSet<>();
}
当直接运行此查询时,它将返回正在查找的确切结果

如果有人能提供帮助,我将不胜感激。我一直在努力找出JPQL语法

谢谢

更新2

在使用“@sb”之后,JPQL似乎不支持右连接。除了找到如何使用左连接(如果可能)在JPQL中编写此代码外,我使用了一个本机查询:

@Query(value = "select tl.* from sync_job sj "+
                "join sync_sending_config ssc on ssc.id = sj.sending_config_id and ssc.id = :sendingConfigId "+
                "join sync_job_transaction_log sjtl on sjtl.sync_job_id = sj.id "+
                "RIGHT JOIN transaction_log tl on tl.id = sjtl.transaction_log_id "+
                "where sjtl.sync_job_id is null", 
                nativeQuery = true)
@QueryHints(value = @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "500"))
Stream<TransactionLog> findTransactionsNotSentForSyncSendingConfigId(@Param("sendingConfigId") long sendingConfigId);
@Query(value=“从同步作业sj中选择tl.*”+
“在ssc.id=sj.sending_config_id和ssc.id=:sendingConfigId上加入同步_sending_config ssc”+
“在sjtl.sync\u job\u transaction\u log sjtl上加入sync\u job\u id=sj.id”+
“右连接tl.id上的事务日志tl=sjtl.transaction\u log\u id”+
“其中sjtl.sync_作业_id为空”,
nativeQuery=true)
@QueryHints(value=@QueryHint(name=org.hibernate.jpa.QueryHints.HINT\u FETCH\u SIZE,value=“500”))
Stream FindTransactionSnotsenforSyncSendingConfigId(@Param(“sendingConfigId”)long sendingConfigId);

假设以下虚拟数据设置:

  • 事务日志ID:1、2、3、4
  • SyncSendingConfig标识:1,2
  • 同步作业:
    • ID 1,SyncSendingConfigID 1
    • ID 2,SyncSendingConfigID 1
    • ID 3,SyncSendingConfigID 2
    • ID 4,SyncSendingConfigID 2
  • 同步\u作业\u事务\u日志
    • SyncJobId 1,TransactionLogId 1
    • SyncJobId 1,TransactionLogId 2
    • SyncJobId 2,TransactionLogId 1
    • SyncJobId 2,TransactionLogId 2
  • 事务日志
    1
    2
    根据sync\u job\u transaction\u log表中的映射,在SyncSendingConfig ID
    1
    下传输。 因此,在SyncSendingConfig ID
    1
    下传输的事务日志不是
    3
    4
    。 因此,为了查找未在给定SyncSendingConfig下传输的事务日志,需要使用相应的JPQL-

    @Query("select t from TransactionLog t where t not in (" +
            "select t1 from TransactionLog t1 join t1.syncJobs tsj where tsj in "
            + "(select sj from SyncJob sj where sj.sendingConfig.id = :sendingConfigId)"
            + ")")
    
    将JPQL视为应用于Java对象的SQL,其中实体表示表,属性表示列,has-a关系表示映射关系。 现在,当您想要连接两个表时,只需参考相应的实体,只要正确指定了连接列,就可以在连接表和列上正确形成SQL查询。 示例SQL-

    select column(s) from table1 <type of> join table2 on table1.column1 = table2.column1 where <filter conditions here>
    
    以上设置的JPQL-

    select property1 from entity1 <type of> join entity1.property2 where <filter condition here>
    

    连接列的另一侧是什么?T1 left join config on config.transmisted=?我的想法是TransactionLog TL可以根据联接表“SyncJob\u TransactionLog”中的TL.id和SJ.id与SyncJob“SJ”联接。然后限制只考虑SJ的结果,其中SJ.id=SyncSendingConfig.id,其中SyncSendConfig=id参数。然后将结果限制在SJ.id为null的位置。请尝试!让我们看看结果。基本上,两个表之间的连接应该至少在每侧的一个相关列之间。我一直在尝试不同的方法来实现查询。。。我将用堆栈跟踪更新问题。但我甚至不确定JPQL的新功能是以什么顺序加入表,或者语法应该是什么样子。只是基于编辑的一个想法,如果您可以获得仅与SyncSendingConfig相关的SyncJobs的列表,那么您可以从TransactionLog的SyncJobs中排除这些SyncJobs?类似于-SELECT tl from TransactionLog tl where t1.syncJobs not in(上面选择的syncJobs)我非常有兴趣学习执行此连接的JPQL语法。当然,但这是否满足了您的需要?我用JPQL构造语法细节更新了答案。我更新了帖子,以包含我正试图编写的与数据相符的SQL查询。当我直接在sql中运行该查询时,它会工作,与postYour sql和我的JPQL中的实体类相匹配,当我按照我答案中的数据设置运行它时,它返回了完全相同的结果。我的JPQL在没有右连接的情况下工作,因为它首先获取针对给定SyncSendingConfig ID传输的TransactionLogs,然后从可用的TransactionLogs中删除所有此类传输的TransactionLogs。
    select column(s) from table1 <type of> join table2 on table1.column1 = table2.column1 where <filter conditions here>
    
    Entity1 (corresponds to table1) -> 
        property1 (corresponds to column)
        property2 (corresponds to mapping relationship, has @JoinColumn details)
    
    select property1 from entity1 <type of> join entity1.property2 where <filter condition here>
    
    @Query(value = "select tl.* from sync_job sj "+
                    "join sync_sending_config ssc on ssc.id = sj.sending_config_id "+
                    "join sync_job_transaction_log sjtl on sjtl.sync_job_id = sj.id "+
                    "RIGHT JOIN transaction_log tl on tl.id = sjtl.transaction_log_id "+
                    "where sjtl.sync_job_id is null and ssc.id = :sendingConfigId", 
                    nativeQuery = true)