【问题标题】:How to translate this working SQL statement to JPA CriteriaBuilder?如何将此工作 SQL 语句转换为 JPA CriteriaBuilder?
【发布时间】:2021-04-11 08:29:42
【问题描述】:

我有三个表:Company、Share 和 Shareholders。 Share 是 Company 和 Shareholder 之间的连接表。

我希望能够仅提取(显示在 UI 中)这些具有给定 security_id 的股东有权访问/共享的公司。

我的问题是我不知道如何将我的工作 sql 查询转换为将用于搜索的谓词。

我使用 Specification 接口和 PredicateBuilder。

实体(仅包含相关字段):

public class Company {
    @Id
    @Column(name = "company_id")
    private Long id;

    @OneToMany(mappedBy = "company")
    private Set<Share> shares;


public class Share {
    @Id
    @Column(name = "share_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "company_id")
    private Company company;

    @ManyToOne
    @JoinColumn(name = "shareholder_id")
    private Shareholder shareholder;

public class Shareholder {
    @Id
    @Column(name = "shareholder_id")
    private Long id;
    
    @Column
    private String securityId;

我在 PredicateBuilder 类中的代码,结果为空:

public CompanyPredicateBuilder access(String securityId) {
    Join<Company, Share> joinShare = root.join(Company.PROPERTY_SHAREHOLDERS);
    Join<Share, Shareholder> joinShareholder = joinShare.join(Share.PROPERTY_SHAREHOLDER);
    Predicate predicate = cb.equal(joinShareholder.get(Shareholder.PROPERTY_SECURITY_ID), securityId);

    predicates.add(predicate);

    return this;
}

然后调用repo中的findAll(query.createSpecification)方法。

最后是有效的 SQL 查询:

SELECT
*
FROM company
JOIN share
ON company.company_id = share.company_id
JOIN shareholder
ON share.shareholder_id = shareholder.shareholder_id
WHERE
shareholder.security_id = 'example'

任何帮助将不胜感激...谢谢!

【问题讨论】:

    标签: java mysql hibernate jpa join


    【解决方案1】:

    看起来您在这里使用了错误的属性,但我无法真正看到这些常量背后的内容:root.join(Company.PROPERTY_SHAREHOLDERS);

    您为什么不使用 Hibernate 生成的静态元模型来避免此类问题,同时更安全?

    【讨论】:

    • 感谢您的回答!我刚刚注意到上面的公司类代码 sn-p 中有一个错误。我编辑了它,现在我确定它没问题。关于这些常量 - 我在指向内部某些字段的实体中使用静态最终字符串,例如:: public static final String PROPERTY_CURRENT_PROJECT_ID = "currentProjectId";指向:私有项目 currentProjectId;同班
    • 您提到的使用这些常量的第一个连接工作正常。我可以创建一个谓词,它工作正常。问题是当我想将第三个表加入到已经创建的加入中时。然后我得到一个空的结果......
    • 生成的 SQL 与您期望的相比是什么?
    • 这其实很有趣,因为它完全一样,虽然它什么也不返回
    • 生成的 SQL:选择不同的 company0_.company_id 作为 company_id1_23_,(...以及所有字段...)从 public.company company0_ 内部加入 public.share share1_ on company0_.company_id=shares1_。 company_id 内部在 share0.shareholder_id=shareholder1_.shareholder_id 上加入 public.shareholdershareholder1_,其中 share0.shareholder_id=shareholder1_.security_id=?限制?
    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 2023-03-12
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    相关资源
    最近更新 更多