JPA one-to-many filtering

陌路散爱 提交于 2019-12-03 23:22:57

AFAIK there is no portable JPA-based way to do this. A clean, however a little bit inefficient, solution would be to do everything on Java-side and create a getter getActiveSystemproperties() that manually iterates over mapped systempropertys and returns an immutable set of active properties.

Another hibernate way of doing it with @Where:

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

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

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

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

I needed to solve similar problem in EclipseLink. I used special SessionCustomizer and changed mapping condition for OneToMany annotation. Maybee Hibernate has something similar.

Add customizer to persistence unit:

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

Fragment of customizer:

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);
          }
        }
      }
    }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!