当前位置: 首页 > 面试题库 >

用于多对多单向关系的Spring Data JPA规范

钱钊
2023-03-14
问题内容

我有一个设置,其中猫可以由许多所有者拥有,每个所有者可以拥有几只猫。鉴于此,我想写一个说明来帮助我找到具有给定主人姓名的所有猫。

这是一个简单的类设置。

@Entity
public class Cat extends AbstractEntity {
  @Column
  private String name;
}

*为简洁起见,没有getters / setter。id字段在超类中。

@Entity
public class Owner extends AbstractEntity {
  @Column
  private String name;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "OWNER_2_CATS", 
        joinColumns = @JoinColumn(name = "OWNER_ID"),
        inverseJoinColumns = @JoinColumn(name = "CAT_ID"))
  @OrderColumn(name = "order_column")
  private List<Cat> cats = Lists.newArrayList();
}

*为简洁起见,没有getters / setter。id字段在超类中。

这是一个存储库,其中包含有效的查询和无效的规范。

public interface CatRepository extends AtomicsRepository<Cat, Long> {

  // This query works.
  @Query("SELECT c FROM Owner o INNER JOIN o.cats c WHERE o.name = ?")
  List<Cat> findAllByOwner(String ownerName);

  // But how do I accomplish this in a specification?
  public static class Specs {
    static Specification<Cat> hasOwnerName(final String ownerName) {
      return (root, query, cb) -> {
        // These next lines don't work! What do I put here?
        Root<Owner> owner = query.from(Owner.class);
        owner.join("cats");
        return cb.equal(owner.get("name"), ownerName);
      };
    }
  }
}

请帮我写规范。

我遇到的麻烦是,这种关系似乎需要与关系的表达方式背道而驰:所有者拥有cats列表,而猫则没有owners列表。


问题答案:

总览

此规范的棘手之处在于,您要查询的 CatOwner 没有直接关系。

总体思路是:

  • 获取 所有者
  • 使用 Owner.cats 关系成员关系将 所有者Cat 相关联。我们可以只使用实体来完成此操作,就像JPA一样为我们处理实体@Id相关性。 __
  • Cat 上的查询标记为 distinct 。为什么?因为这是@ManyToMany关系,并且根据所 使用的所有者 条件,任何给定的 Cat 可能都有多个匹配的 所有者

方法1-子查询

我的首选方法是使用子查询来引入 Owner

// Subquery using Cat membership in the Owner.cats relation
public static class Specs {
    static Specification<Cat> hasOwnerName(final String ownerName) {
        return (root, query, cb) -> {
            query.distinct(true);
            Root<Cat> cat = root;
            Subquery<Owner> ownerSubQuery = query.subquery(Owner.class);
            Root<Owner> owner = ownerSubQuery.from(Owner.class);
            Expression<Collection<Cat>> ownerCats = owner.get("cats");
            ownerSubQuery.select(owner);
            ownerSubQuery.where(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
            return cb.exists(ownerSubQuery);
        };
    }
}

哪个Hibernate 4.3.x会生成SQL查询,例如:

select cat0_.id as id1_1_
from cat cat0_
where 
    exists (
        select owner1_.id from owner owner1_ where
            owner1_.name=?
            and (cat0_.id in (
                select cats2_.cat_id from owner_2_cats cats2_ where owner1_.id=cats2_.owner_id
            ))
    )

方法2-笛卡尔积

一种替代方法是使用笛卡尔积介绍 所有者

// Cat membership in the Owner.cats relation using cartesian product
public static class Specs {
    static Specification<Cat> hasOwnerName(final String ownerName) {
        return (root, query, cb) -> {
            query.distinct(true);
            Root<Cat> cat = root;
            Root<Owner> owner = query.from(Owner.class);
            Expression<Collection<Cat>> ownerCats = owner.get("cats");
            return cb.and(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
        };
    }
}

哪个Hibernate 4.3.x会生成SQL查询,例如:

select cat0_.id as id1_1_
from cat cat0_
cross join owner owner1_
where
    owner1_.name=?
    and (cat0_.id in (
        select cats2_.cat_id from owner_2_cats cats2_ where owner1_.id=cats2_.owner_id
    ))


 类似资料:
  • 我有两个类:< code>User和< code>UserProfile。 用户类别: 用户配置文件类: 当我使用此代码时,我在具有多对多关系的表用户配置文件中获得重复的实体。我使用 函数来保存对象。我做错了什么? 然后我删除 cascadeType,出现错误:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。 Hibernate日志:

  • 假设我们有两个实体,Entity和Entity。有多个s。节点可以属于多个集群。因此,在

  • 我有一个设置,猫可以由许多主人拥有,每个主人可以拥有几只猫。有鉴于此,我想写一个规范来帮助我找到所有拥有给定主人名字的猫。 下面是一个简单的类设置。 *简洁性方面没有获得者/接受者。Id字段位于超类中。 *简洁性方面没有获得者/接受者。Id字段位于超类中。 这是一个存储库,其中有一个有效的查询和一个无效的规范。 请帮我写一下说明书。 我遇到的问题是,这种关系似乎需要与这种关系的表达方式背道而驰:主

  • 本文向大家介绍Django 简单的多对多关系。,包括了Django 简单的多对多关系。的使用技巧和注意事项,需要的朋友参考一下 示例 在这里,我们定义了一种关系,其中一个俱乐部有许多Persons和成员,一个人可以是几个不同Clubs的成员。 尽管我们仅定义了两个模型,但django实际上为我们在数据库中创建了三个表。这些myapp_person,myapp_club和myapp_club_mem

  • MongoDB多对多关联 如何在MongoDB中组织多对多关系 我在这种设置中看到的问题是MongoDB的16MB文档限制。假设我有s、s和s。有一个关联的和许多可能喜欢它的。中有许多和许多可以跟随它。一个可以有许多喜欢的并且可以跟随许多。如果我要用一个关系数据库来构建它,我会这样设置它: 理论上,如果在SQL查询中正确分页,则可以有有限数量的和跟随的;可以有无限数量的喜欢的;可以有无限数量的喜欢

  • 问题内容: 我已经阅读了许多有关级联和多对多关联的主题,但是我无法找到我的特定问题的答案。 我在UserProfiles和Roles之间有多对多关系。当我删除UserProfile时,我希望数据库删除联接表(userprofile2role)中的关联记录,因此要使用实际的SQL’ON DELETE CASCADE’操作。这可能吗?无论我尝试什么,Hibernate总是在不指定ON DELETE行为