28

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

@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;
}

请求时,Systemproperties我只想获取active( active = 1 ) 的属性。

环顾四周,我发现了一些休眠注释和使用子查询的可能性。但是,两者都不适合我。尽管我们目前正在使用休眠,但我正在考虑用 Eclipselink 替换它,因为我们目前必须使用急切加载,并且很可能会遇到性能问题。子查询并不能很好地工作,因为我们嵌套了几个级别。

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

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

4

4 回答 4

25

使用@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;
}
于 2017-04-05T18:50:13.643 回答
7

AFAIK 没有可移植的基于 JPA 的方法来执行此操作。一个干净但有点低效的解决方案是在 Java 端做所有事情并创建一个getActiveSystemproperties()手动迭代映射systempropertys并返回一组不可变的活动属性的 getter。

于 2012-11-09T10:50:35.283 回答
2

我需要在 EclipseLink 中解决类似的问题。我使用了特殊的 SessionCustomizer 并更改了 OneToMany 注释的映射条件。Maybee Hibernate 也有类似的东西。

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

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);
          }
        }
      }
    }
    }
}
于 2014-03-20T07:53:13.790 回答
1

没有 JPA 方式,但您可以尝试 Hibernate filetrs:http ://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-filters

于 2013-09-05T09:36:28.287 回答