有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JPA onetomany过滤

我们正在嵌套几个实体。然而,在检索时,我们只想获取那些活动的实体

@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活动=1)的属性

我四处搜索,发现了一些hibernate annotations和使用subqueries的可能性。然而这两种方法对我来说都不管用。尽管我们目前使用的是hibernate,但我正在考虑用Eclipselink来代替它,因为我们目前必须使用即时加载,这可能会导致性能问题。子查询并不能很好地工作,因为我们嵌套了几个级别

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

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


共 (4) 个答案

  1. # 2 楼答案

    另一种使用@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;
    }
    
  2. # 3 楼答案

    AFAIK没有基于JPA的便携式方法来实现这一点。一个干净但效率有点低的解决方案是在Java端执行所有操作,并创建一个getter getActiveSystemproperties(),手动迭代映射的systempropertys,并返回一组不可变的活动属性

  3. # 4 楼答案

    我需要在日食中解决类似的问题。我使用了特殊的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);
              }
            }
          }
        }
        }
    }