【问题标题】:How to write a Jpa Specification to join two tables?如何编写 Jpa 规范来连接两个表?
【发布时间】:2018-03-27 03:47:15
【问题描述】:

假设我有两个如下实体:

@Data
@Entity
@Table(name = "reward")   
public class Reward{

  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
  @Column(length = 36)
  private String id;

  private String sn;

  //other fields

}


@Data
@Entity
@Table(name = "strategy_rewards")
public class RewardUserRelation{

  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
  @Column(length = 36)  
  private String id; 

  private String uid;

  private String rid; //reward id

  //other fields;    

}

我还编写了一些其他规范,如下所示,以从 mysql 过滤我的奖励数据并将它们返回给其他服务:

public static Specification<Reward> withSn(String sn) {
    return (root, query, builder) -> builder
        .like(root.get("sn"), "%" +sn + "%");
  }

Page result = rewardRepository.findAll(where(sn == null ? null : 
    RewardSpecs.withSn(sn)), pageable));

但现在我想完成一个规范,它可以过滤 id 未出现在 RewardUserRelation 表中的奖励,这意味着这些奖励是未使用的。我已经搜索了几个规范教程,但仍然无法解决。我应该使用 Join Criteria Api 吗?但我不知道该怎么做。 :(

更新:不知何故,我设法通过提前从关系表中选择 all rid 并使用 Expression.in() 来解决这个问题,但仍然想知道是否有更好的方法来做到这一点。

List<String> idList =strategyRewardRelationRepository.getByDeleted(false).stream()
.map(StrategyRewardRelation::getRid).distinct().collect(Collectors.toList());

public static Specification<Reward> withUsed(Boolean used, List<String> idList) {
    return (root, query, builder) -> {
      return used ? root.get("id").in(idList) : root.get("id").in(idList).not();
    };
 }

【问题讨论】:

  • 我很好奇为什么你有一个RewardUserRelation 类,因为中间表应该由@ManyToMany 关系在内部处理。
  • 我在您的实体类中看不到任何 OneToManyManyToOne 关系。您是否故意删除它们以发布此问题,并且您的原始代码中是否包含它们?因为条件连接需要关联导航。
  • @MadhusudanaReddySunnapu 不,我没有使用任何 OneToManyManyToOne 注释
  • 您的实体RewardRewardUserRelation 有什么关系?我什至没有看到任何@Entity 或@id 注释?您是否可以通过代码将Reward 实体保存在数据中?
  • @MadhusudanaReddySunnapu 我添加了一些错过的代码,我可以简单地通过rewardRepository.save() 保存奖励

标签: java spring hibernate spring-data-jpa criteria


【解决方案1】:

Specification 中的两个联接可能是要走的路:

case "propertyId":
                Join<SourceEntity, Item> itemJoin = root.join("item");
                Join<SourceEntity, ItemSourceDetail> itemDetailJoin = itemJoin.join("itemSourceDetail");
                try {
                    filterValue = criteria.getString(key).toString();
                    filters.add(itemDetailJoin.get("propertyId").in(Long.valueOf(filterValue)));
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 2023-03-24
    相关资源
    最近更新 更多