Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA一对多过滤_Java_Jpa_One To Many - Fatal编程技术网

Java JPA一对多过滤

Java JPA一对多过滤,java,jpa,one-to-many,Java,Jpa,One To Many,我们正在嵌套几个实体。然而,在检索时,我们只想获取那些活动的实体 @Entity public class System { @Id @Column(name = "ID") private Integer id; @OneToMany(mappedBy = "system") private Set<Systemproperty> systempropertys; } @Entity public class Systemproperty { @Id

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

@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;
}
@实体
公课制{
@身份证
@列(name=“ID”)
私有整数id;
@OneToMany(mappedBy=“系统”)
私有设置系统属性;
}
@实体
公共类Systemproperty{
@身份证
@列(name=“ID”)
私有整数id;
@身份证
@列(name=“ACTIVE”)
私有整数活动;
}
当请求
Systemproperties
时,我只想获取
活动的属性(活动=1)

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

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


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

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

没有JPA方法,但您可以尝试HibernateFileTrs:

我需要在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);
          }
        }
      }
    }
    }
}
公共类MySessionCustomizer实现SessionCustomizer{
public void自定义(会话)引发异常{
final Map descs=session.getDescriptors();
如果(描述!=null)
{
//这段代码假设每个描述符只有一个表!
对于(最终对象descObj:descs.values())
{
最终类描述符desc=(类描述符)descObj;
最终类sourceClass=desc.getJavaClass();
for(数据库映射:desc.getMappings())
{
if(onetomanaymapping的映射实例)
{
最终OneToNameMapping集合映射=((OneToNameMapping)映射);
//创建默认外键条件(必要):
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));
//添加过滤条件“additionalExpression”
最终表达式finalExpression=defaultFkExpression.and(additionalExpression);
//将默认外键条件和筛选条件设置为映射
映射。设置选择标准(最终表达式);
}
}
}
}
}
}

另一种hibernate方式:

@实体
公课制{
@身份证
@列(name=“ID”)
私有整数id;
@OneToMany(mappedBy=“系统”)
@其中(clause=“active=true”)
私有设置系统属性;
}
@实体
公共类Systemproperty{
@身份证
@列(name=“ID”)
私有整数id;
@身份证
@列(name=“ACTIVE”)
私有整数活动;
}

稍微有点不正常,但是您确定
活动的
应该是
系统属性
ID的一部分吗?所以@Filter不适合您?@AdamDyga我会把旧的系统属性踢出去,但是,这会违反某些外键。@AleksandrM我更喜欢上面提到的非休眠依赖解决方案。@AleksandrM
@Filter
如果直接获取实体(例如
EntityManager.find()
)。当您通过JPA/Hibernate映射的
集合
集合
获取实体时,它不会应用。您已保存了我的一天。如果SystemProperty中的某些属性在SystemProperty类中不存在,该怎么办。
@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;
}