JPA one-to-many filtering

前端 未结 4 1903
遇见更好的自我
遇见更好的自我 2021-02-05 05:20

We are nesting several entities. However upon retrieving we only want to get those entities which are active.

@Entity
public class System {
  @Id
  @Column(name          


        
相关标签:
4条回答
  • 2021-02-05 05:45

    There is no JPA way, but you can try Hibernate filetrs: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-filters

    0 讨论(0)
  • 2021-02-05 05:53

    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);
              }
            }
          }
        }
        }
    }
    
    0 讨论(0)
  • 2021-02-05 05:54

    Another hibernate way of doing it with @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;
    }
    
    0 讨论(0)
  • 2021-02-05 06:08

    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.

    0 讨论(0)
提交回复
热议问题