当前位置: 首页 > 知识库问答 >
问题:

JPA一对多过滤

朱祺
2023-03-14

我们嵌套了几个实体。但是在检索时,我们只想获取那些活动的实体。

@Entity
public class System {
  @Id
  @Column(name = "ID")
  private Integer id;

  @OneToMany(mappedBy = "system")
  private Set<Systemproperty> systempropertys;
}

@Entity
public class Systemproperty {
  @Id
  @Column(name = "ID")
  private Integer id;

  @Id
  @Column(name = "ACTIVE")
  private Integer active;
}

请求系统属性时,我只想获取处于活动状态的属性(active = 1)。

搜索了一下,我发现了一些Hibernate注释和使用子查询的可能性。然而,这两种都不适合我。尽管我们目前正在使用Hibernate,但我正在考虑用Eclipselink替换它,因为我们目前必须使用急切加载,我们可能会遇到性能问题。子查询实际上效果不好,因为我们嵌套了几个级别。

Eclipseelink似乎有一个@Customizer注释可以工作,但它似乎遵循了与hibernate@FilterDef注释不同的概念,并且在切换时会导致额外的开销。

@JoinColumn似乎不允许进一步筛选。有没有标准的JPA方法来解决这个问题?

共有3个答案

丁嘉
2023-03-14

我需要在日食链接中解决类似的问题。我使用了特殊的会话自定义器并更改了 OneToMany 注释的映射条件。梅比冬眠也有类似的东西。

将定制器添加到持久性单元:

props.put(PersistenceUnitProperties.SESSION_CUSTOMIZER,MySessionCustomizer.class.getName());
EntityManagerFactory factory = new PersistenceProvider().createEntityManagerFactory(pu.getPersistenceUnitName(), props);

自定义程序片段:

public class MySessionCustomizer implements SessionCustomizer {
    public void customize(Session session) throws Exception {
        final Map<?, ?> descs = session.getDescriptors();
    if (descs != null)
    {
      // This code assumes single table per descriptor!
      for (final Object descObj : descs.values())
      {
        final ClassDescriptor desc = (ClassDescriptor) descObj;
        final Class<?> sourceClass = desc.getJavaClass();

        for (DatabaseMapping mapping : desc.getMappings())
        {
          if (mapping instanceof OneToManyMapping)
          {
            final OneToManyMapping collectionMapping = ((OneToManyMapping) mapping);

            // create default foreign key condition (nescessary):
            final DatabaseField sourceField = mapping.getSourceKeyFields().get(0);
            final DatabaseField targetField = mapping.getTargetForeignKeyFields().get(0);
            final Expression defaultFkExpression =  new ExpressionBuilder(mapping.getReferenceClass()).getParameter(sourceField).equal(eb.getField(targetField));

            // add filter condition "additionalExpression"
            final Expression finalExpression = defaultFkExpression.and(additionalExpression);

             // SET default foreign key condition and filter condition to mapping
             mapping.setSelectionCriteria(finalExpression);
          }
        }
      }
    }
    }
}
扈德容
2023-03-14

AFAIK没有基于JPA的便携式方法来实现这一点。一个干净但有点低效的解决方案是在Java端做所有事情,并创建一个gettergetActiveSystemproperties(),它手动迭代映射的系统属性并返回一组不可变的活动属性。

堵凯
2023-03-14

另一种冬眠方式是使用@where:

@Entity
public class System {
  @Id
  @Column(name = "ID")
  private Integer id;

  @OneToMany(mappedBy = "system")
  @Where(clause = "active = true")
  private Set<Systemproperty> systempropertys;
}

@Entity
public class Systemproperty {
  @Id
  @Column(name = "ID")
  private Integer id;

  @Id
  @Column(name = "ACTIVE")
  private Integer active;
}
 类似资料:
  • 主要内容:@ManyToOne 示例,程序输出结果多对一映射表示实体集合可以与相似实体关联的单值关联。 因此,在关系数据库中,实体的多于一行可以引用另一个实体的相似行。 完整的项目目录结构如下所示 - @ManyToOne 示例 在这个例子中,我们将创建一个学生和图书库之间的多对一关系,多个学生可以发布同一本书。 这个例子包含以下步骤 - 第1步: 在包中创建一个实体类,包含学生ID(s_id)和学生姓名(s_name),其中包含一个包含库类型对

  • 主要内容:@OneToMany 示例,程序输出结果一对多映射进入集合值关联的类别,其中实体与其他实体的集合关联。 因此,在这种类型的关联中,一个实体的实例可以映射到另一个实体的任意数量的实例。 完整的项目目录结构如下所示 - @OneToMany 示例 在这个例子中,我们将创建一个学生和图书库之间的一对多系,这样一个学生能发放多种类型的图书。 这个例子包含以下步骤 - 第1步: 在包下创建一个实体类,它包含学生ID(s_id),学生姓名(s_na

  • 我想通过向个人实体添加地址列表来扩展使用REST访问JPA数据的示例。因此,我添加了一个带有注释的列表地址: 地址类是一个非常简单的类: 最后,我添加了AddressRepository界面: 然后我试着给一个人发一些地址: 我得到的错误是: 创建一对多和多对多关系并向其发布json对象的正确方法是什么?

  • 我调试了代码,变量“empresasucursal”嵌入了大量相同的信息,导致内存溢出。根据下图的数据库模型,正确的方法是什么 [![empresa_sucursal][1]][1] Java Empresa类 Java类 Java EmpresaSucursal类 控制器方法 控制台出错 017-04-17 10:05:10.442警告9788-[nio-8080-exec-1]。w、 s.m.

  • 问题内容: 也许这是一个愚蠢的问题,但这困扰了我。 我有一个从员工到车辆的双向一对多关系。当我第一次将Employee保留在数据库中时(即它没有分配的ID),我也希望保留其关联的Vehicles。 目前,这对我来说很好,除了我保存的Vehicle实体没有自动映射关联的Employee,并且在数据库中Vehicle表中的employee_id外键列为空。 我的问题是,是否可以在雇员本身被保留的同时保

  • 我有两个JPA实体(账户和个人),具有双向关系: 当我持久化一个人时,我不想持久化所有帐户,但当我持久一个帐户时,我想更新Person属性hasAccounts,因此我还需要更新这个人。 我做了以下步骤: 创建人员 坚持该人 创建帐户 修改所有者(以前创建的 持久帐户(我希望它会自动合并该人) 我得到了这个例外: (我用JPA 1.0配合Hibernate)。