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
Hibernate 无法使用Spring数据Rest在服务器端按子实体字段排序_Hibernate_Spring Boot_Pagination_Spring Data Jpa_Spring Data Rest - Fatal编程技术网

Hibernate 无法使用Spring数据Rest在服务器端按子实体字段排序

Hibernate 无法使用Spring数据Rest在服务器端按子实体字段排序,hibernate,spring-boot,pagination,spring-data-jpa,spring-data-rest,Hibernate,Spring Boot,Pagination,Spring Data Jpa,Spring Data Rest,我正在用Spring数据REST和Spring数据JPA实现服务器端排序。JPA实体我想按多对一实体budgetPool.name对结果进行排序 @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "TYPE", discriminatorType =DiscriminatorType.STRING) @Table(name = "PS_TRANSACTION")

我正在用Spring数据REST和Spring数据JPA实现服务器端排序。JPA实体我想按多对一实体budgetPool.name对结果进行排序

@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "TYPE", discriminatorType =DiscriminatorType.STRING) 
@Table(name = "PS_TRANSACTION") 
@ActiveBudgetPoolValidation 
public abstract class Transaction extends Auditable {
    @Id
    @Column(name = "ID", nullable = false, insertable = false, updatable = false)
    @SequenceGenerator(name = "TransactionSeq", sequenceName = "SEQ_TRANSACTION", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TransactionSeq")
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    protected Long id;

    @NotNull
    @JsonProperty(access = READ_WRITE)
    @ManyToOne(optional = false)
    @JoinColumn(name = "BUDGET_POOL_ID", referencedColumnName = "ID", updatable = false)
    protected BudgetPool budgetPool;
我在UI上显示budgetPool.name,并选择按预算池名称对结果进行排序。以下URL用于按id工作对预算池进行排序:

http://host:port/finance-service/transactions/search/approvals?page=0&size=10&sort=budgetPool,desc
但以下按预算池名称排序的url引发java.sql.SQLSyntaxErrorException:按表达式排序无效:

My Repository有一个自定义查询,根据传递的搜索参数返回分页事务

@RepositoryRestResource(excerptProjection = TransactionWithInlineProductControlAction.class, collectionResourceRel = "transactions")
    public interface TransactionRepository<T extends Transaction> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {
    @RestResource(path = "approvals", rel = "approvals", description = @Description("Show approval transactions for the given status, orderId and budgetPoolId (paged)"))
        @Query("SELECT DISTINCT t " +
                "FROM Transaction t " +
                "JOIN t.budgetPool bp " +
                "LEFT JOIN bp.budgetApprovers ba " +
                "LEFT JOIN bp.technicalApprovers ta " +
                "WHERE (t.status = :status OR :status IS NULL) " +
                "AND (t.autoApproved = false OR t.autoApproved IS NULL) " +
                "AND (t.orderId LIKE %:orderId% OR :orderId IS NULL) " +
                "AND (bp.id=:budgetPoolId OR :budgetPoolId IS NULL) " +
                "AND (" +
                "ta.email LIKE ?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_SERVICE_ACCOUNT') ? '%' : principal.username} " +
                "OR ba.email LIKE ?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_SERVICE_ACCOUNT') ? '%' : principal.username} " +
                "OR 1=?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_COMMERCIAL_MANAGEMENT') || hasRole('ROLE_PRODUCT_MANAGEMENT') ? 1 : 0}" +
                ")"
        )   
        Page<T> findByStatusAndBudgetPool(
                @Param("status") TransactionStatus status,
                @Param("orderId") String orderId,
                @Param("budgetPoolId") Long budgetPoolId,
                Pageable p
        );
    }
通过在select语句中添加budgetpool1.NAME,上述查询可以正常工作。也许解决方案可以告诉JPA/Hibernate在顶级实体中包含预算池名称,但我没能成功做到这一点

我在不同的论坛上搜索过,但没有找到答案。我提前感谢你的帮助


我提前感谢您的帮助。

那么失败的SQL是什么样子的呢?嗨,艾伦,上面提供了失败的SQL抛出SQL错误:ORA-01791:通过在select语句中添加budgetpool1_u1;.NAME,上面的查询中没有选定的表达式可以正常工作。如果我理解正确,则可能重复上面链接中解释的问题与本机SQL查询相关,而不是HQL。如上所述,我可以使用本机SQL解决这个问题,但这并不能解决我的问题。我正在使用SpringDataREST,我想知道如何让SpingG/JPA/Hibernate在父select语句中包含这个额外的ORDERBY字段(budgetpool1_uu1;.NAME),或者是否有其他方法按子实体字段排序父实体。谢谢
@RepositoryRestResource(excerptProjection = TransactionWithInlineProductControlAction.class, collectionResourceRel = "transactions")
    public interface TransactionRepository<T extends Transaction> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {
    @RestResource(path = "approvals", rel = "approvals", description = @Description("Show approval transactions for the given status, orderId and budgetPoolId (paged)"))
        @Query("SELECT DISTINCT t " +
                "FROM Transaction t " +
                "JOIN t.budgetPool bp " +
                "LEFT JOIN bp.budgetApprovers ba " +
                "LEFT JOIN bp.technicalApprovers ta " +
                "WHERE (t.status = :status OR :status IS NULL) " +
                "AND (t.autoApproved = false OR t.autoApproved IS NULL) " +
                "AND (t.orderId LIKE %:orderId% OR :orderId IS NULL) " +
                "AND (bp.id=:budgetPoolId OR :budgetPoolId IS NULL) " +
                "AND (" +
                "ta.email LIKE ?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_SERVICE_ACCOUNT') ? '%' : principal.username} " +
                "OR ba.email LIKE ?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_SERVICE_ACCOUNT') ? '%' : principal.username} " +
                "OR 1=?#{hasRole('ROLE_ADMIN') || hasRole('ROLE_COMMERCIAL_MANAGEMENT') || hasRole('ROLE_PRODUCT_MANAGEMENT') ? 1 : 0}" +
                ")"
        )   
        Page<T> findByStatusAndBudgetPool(
                @Param("status") TransactionStatus status,
                @Param("orderId") String orderId,
                @Param("budgetPoolId") Long budgetPoolId,
                Pageable p
        );
    }
select distinct transactio0_.ID as ID2_10_, transactio0_.LAST_MODIFIED_DATE as LAST_MOD3_10_, transactio0_.VERSION as VERSION4_10_, transactio0_.COMMENTS as COMMENTS5_10_, 
transactio0_.CREATED_BY as CREATED_6_10_, transactio0_.CREATED_DATE as CREATED_7_10_, transactio0_.LAST_MODIFIED_BY as LAST_MOD8_10_, transactio0_.APPROVED as APPROVED9_10_, 
transactio0_.AUTO_APPROVED as AUTO_AP10_10_, transactio0_.BUDGET_POOL_ID as BUDGET_23_10_, transactio0_.CLARITY_ID as CLARITY11_10_, transactio0_.CLARITY_PROJECT_NAME as CLARITY12_10_, 
transactio0_.PRODUCT_CONTROL_ACTION_ID as PRODUCT24_10_, transactio0_.AMOUNT as AMOUNT13_10_, transactio0_.DESCRIPTION as DESCRIP14_10_, transactio0_.INITIAL_COST as INITIAL15_10_, 
transactio0_.NAR_INSTANCE_ID as NAR_INS16_10_, transactio0_.NAR_INSTANCE_NAME as NAR_INS17_10_, transactio0_.NEXT_YEAR_COST as NEXT_YE18_10_, transactio0_.ORDER_ID as ORDER_I19_10_, 
transactio0_.REFERENCE_LINK as REFEREN20_10_, transactio0_.REQUESTOR as REQUEST21_10_, transactio0_.STATUS as STATUS22_10_, transactio0_.TYPE as TYPE1_10_ 
from PS_TRANSACTION transactio0_ 
inner join PS_BUDGET_POOL budgetpool1_ on transactio0_.BUDGET_POOL_ID=budgetpool1_.ID 
left outer join PS_PARTICIPANT budgetappr2_ on budgetpool1_.ID=budgetappr2_.BUDGET_POOL_ID 
and ( budgetappr2_.TYPE = 'BUDGET' AND budgetappr2_.ACTIVE=1)  
and budgetappr2_.TYPE='BUDGET' 
left outer join PS_PARTICIPANT technicala3_ on budgetpool1_.ID=technicala3_.BUDGET_POOL_ID 
and ( technicala3_.TYPE = 'TECHNICAL' AND technicala3_.ACTIVE=1)  
and technicala3_.TYPE='TECHNICAL' where 1=1 and 1=1 and 1=1 
and (transactio0_.AUTO_APPROVED is null or transactio0_.AUTO_APPROVED=false) 
and (budgetappr2_.EMAIL like ? or technicala3_.EMAIL like ? or 1=1) 
order by budgetpool1_.NAME desc limit ?