【发布时间】: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关系在内部处理。 -
我在您的实体类中看不到任何
OneToMany或ManyToOne关系。您是否故意删除它们以发布此问题,并且您的原始代码中是否包含它们?因为条件连接需要关联导航。 -
@MadhusudanaReddySunnapu 不,我没有使用任何
OneToMany或ManyToOne注释 -
您的实体
Reward和RewardUserRelation有什么关系?我什至没有看到任何@Entity 或@id 注释?您是否可以通过代码将Reward实体保存在数据中? -
@MadhusudanaReddySunnapu 我添加了一些错过的代码,我可以简单地通过rewardRepository.save() 保存奖励
标签: java spring hibernate spring-data-jpa criteria