Вопрос по java, jpa, one-to-many – JPA фильтрация один ко многим

13

Мы вкладываем несколько объектов. Однако при получении мы хотим получить только те объекты, которые активны.

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

  @OneToMany(mappedBy = "system")
  private Set systempropertys;
}

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

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

При запросеSystemproperties Я только хочу получить свойства, которые являются (activeактивный = 1).

В поисках я нашел несколькоспящие аннотации и возможность использованияподзапросы, Однако оба неэто действительно работает для меня. Хотя мы в настоящее время используем спящий IЯ собираюсь заменить его на Eclipselink, потому что в настоящее время мы должны использовать стремительную загрузку, и мы, вероятно, столкнемся с проблемами производительности. Подзапросы неэто действительно хорошо работает, потому что мы вложили несколько уровней.

Eclipselink, кажется, имеет@Customizer аннотация, которая может работать, однако, похоже, она следует другой концепции, чем спящий@FilterDef аннотации и вызовет дополнительные издержки при переключении.

@JoinColumn Безразлично»Кажется, для дальнейшей фильтрации. Существует ли стандартный способ JPA для решения этой проблемы?

Ну, ограничения внешнего ключа начинаются. Roman C
Так @Filter не работает для вас? Aleksandr M
@AleksandrM@Filter работает, если получить объект напрямую (например,EntityManager.find() ). Это'не применяется, когда вы получаете объекты черезSet или жеCollection это сопоставлено с JPA / Hibernate Adam Dyga
@AleksandrM I 'я бы предпочел не зависящее от спящего режима решение, как упомянуто выше. Udo Held

Ваш Ответ

4   ответа
3

Еще один спящий способ сделать это с@Куда:

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

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

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

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

AFAIK нет портативного способа на основе JPA, чтобы сделать это. Чистым, хотя и немного неэффективным решением было бы сделать все на стороне Java и создать геттер.getActiveSystemproperties() который вручную перебирает картуsystempropertys и возвращает неизменный набор активных свойств.

1

Мне нужно было решить подобную проблему в EclipseLink. Я использовал специальный SessionCustomizer и изменил условие отображения для аннотации OneToMany. Возможно, в 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);
          }
        }
      }
    }
    }
}
1

Нет способа JPA, но вы можете попробовать Hibernate filetrs:http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-filters

Похожие вопросы