hibernate 休眠条件:没有Map关联的连接表

o75abkj4  于 2023-08-06  发布在  其他
关注(0)|答案(6)|浏览(116)

我想使用Hibernate的criteria API构造一个连接两个实体的特定查询。假设我有两个实体,宠物和主人,其中一个主人有许多宠物,但关键的是,这种关联没有在Java注解或xml中Map。
使用hql,我可以通过在查询中指定连接来选择拥有宠物“fido”的主人(而不是向主人类中添加一组宠物)。
是否可以使用休眠条件来完成相同的操作?若有,该如何处理?
谢了,J

v64noz0r

v64noz0r1#

这实际上是可能的,具有以下标准:

DetachedCriteria ownerCriteria = DetachedCriteria.forClass(Owner.class);
ownerCriteria.setProjection(Property.forName("id"));
ownerCriteria.add(Restrictions.eq("ownername", "bob"));

Criteria criteria = getSession().createCriteria(Pet.class);
criteria.add(Property.forName("ownerId").in(ownerCriteria));

字符串

更新:这实际上是执行子查询而不是连接,但它允许您在两个没有定义hibernate关系的实体上使用Criteria。

r8xiu3jd

r8xiu3jd2#

我的理解是,如果你使用HQL做这件事,你是在创建一个带有过滤器的笛卡尔连接,而不是一个内部连接。条件查询不支持这样做。

r9f1avp5

r9f1avp53#

在NHibernate中,您可以使用定义为DetachedCriteria的子查询。不确定它在Java中的工作方式是否相同,但很可能是相同的:

DetachedCriteria pets = DetachedCriteria.For<Pet>("pet")
  .SetProjection(Projections.Property("pet.ownername"))
  .Add(/* some filters */ );

session.CreateCriteria(typeof(Owner))
  .Add(Subqueries.PropertyIn("name", pets);

字符串
假设它是使用拥有者的名称来链接。

fhity93d

fhity93d4#

Criterion ownerCriterion = Restrictions.sqlRestriction(SELECT ownerId FROM   Owner WHERE ownerName ='bob');
Criteria criteria = getSession().createCriteria(Pet.class);
criteria.createCriteria("ownerId").add(ownerCriterion);

字符串

gcuhipw9

gcuhipw95#

此时,这可以通过以下方式实现:
Spring data JPA 2.1.10我有两个实体:

@Entity
@Getter
@Setter
public class TaskManagement {
  private Long id;
  private String title;
  //Some other attributes
}

@Entity
@Getter
@Setter
public class Tagging {
  private Long id;
  private String name;
  private String taskManagementId;
  //Some other attributes
}

字符串
任务可以有一些标记。但是TaskManagement和Tag实体之间没有任何关系。
为了搜索taskmanagements,我使用了TaskManagementSpecification,如下所示:

public class TaskManagementSpecification implements Specification<TaskManagement> {
  private final TaskManagementSearchDto taskManagementSearchDto;

  @Override
  public Predicate toPredicate(Root<TaskManagement> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    List<Predicate> andClause = new ArrayList<>();

    //To Cross join TaskManagement to Tagging that they are unrelated
    if (!CollectionUtils.isEmpty(taskManagementSearchDto.getTagIds())) {
      Root<Tagging> taggingRoot = criteriaQuery.from(Tagging.class);

      andClause.add(criteriaBuilder.equal(taggingRoot.get("taskManagementId"), root.get(TaskManagement_.ID)));        
    }
  }
}


结果查询为:

select foo
from task_management taskmanage0_
     cross join tagging tagging1_
where tagging1_.task_mangement_id = taskmanage0_.id

bxfogqkk

bxfogqkk6#

有一个SQLCriterion,你可以给予任意的SQL,并添加到你的Criteria。在SQL字符串中,标记“{alias}”将替换为根实体的别名。

相关问题