аннотация для фильтрации результатов ассоциации @OneToMany - PullRequest
20 голосов
/ 03 августа 2011

У меня есть отношения родитель / потомок между двумя таблицами и соответствующее отображение в моих классах Java.Таблицы примерно выглядят так:

A (ref number, stuff varchar2(4000))
B (a_ref number, other number, foo varchar2(200))

и код Java:

@Entity
class A {
    @Id
    @Column(name = "REF")
    private int ref;

    @OneToMany
    @JoinColumn(name = "A_REF", referencedName = "REF")
    private Set<B> bs;
}

@Entity
class B {
    @Id
    @Column(name = "A_REF")
    private int aRef;

    @Id
    @Column(name = "OTHER")
    private int other;
}

Это работает нормально, но я хотел бы добавить фильтр для строк, которые я получаю издетский стол.Сгенерированный запрос выглядит следующим образом:

select a_ref, other, foo from B where a_ref = ?

И я бы хотел, чтобы он был:

select a_ref, other, foo from B where a_ref = ? and other = 123

Дополнительным фильтром будет только имя столбца и жестко заданное значение,Есть ли способ сделать это, используя аннотации hibernate?

Я смотрел на @JoinFormula, но с этим мне всегда приходится ссылаться на имя столбца из родительской таблицы (в атрибуте nameJoinFormula).

Заранее благодарен за любые советы.

Ответы [ 3 ]

28 голосов
/ 03 августа 2011

Это не поддерживается JPA, но если вы используете hibernate в качестве поставщика JPA, то вы можете использовать аннотации @FilterDef и @Filter.

Справочная документация по Hibernate Core

Hibernate3 имеет возможность предварительно определять критерии фильтрации и прикреплять эти фильтры как на уровне класса, так и на уровне коллекции. Фильтр Критерий позволяет определить ограничение, похожее на существующий атрибут "где" доступен в классе и различные элементы коллекции. Эти условия фильтрации, однако, могут быть параметризованных. Затем приложение может решить во время выполнения определенные фильтры должны быть включены и каковы их значения параметров должно быть. Фильтры могут использоваться как представления базы данных, но они параметризован внутри приложения.

Пример

@Entity
public class A implements Serializable{
    @Id
    @Column(name = "REF")
    private int ref;

    @OneToMany
    @JoinColumn(name = "A_REF", referencedColumnName = "REF")   
    @Filter(name="test")
    private Set<B> bs;
}

@Entity
@FilterDef(name="test", defaultCondition="other = 123")
public class B implements Serializable{
    @Id
    @Column(name = "A_REF")
    private int aRef;

    @Id
    @Column(name = "OTHER")
    private int other;
}

Session session = entityManager.unwrap(Session.class);
session.enableFilter("test");
A a = entityManager.find(A.class, new Integer(0))
a.getb().size() //Only contains b that are equals to 123
2 голосов
/ 26 февраля 2015

с JPA 1 вы можете использовать предоставленное решение, но измените развертку на getDelegate, чтобы она была такой же

Session session = (Session)entityManager.getDelegate();

, и она будет работать.

0 голосов
/ 14 октября 2016

Если я правильно понял вопрос, есть способ сделать это с помощью аннотаций javax.persistence (я сам использовал это на ManyToOne и адаптировал ответ от здесь ):

@JoinColumns({
    @JoinColumn(name = "A_REF", referencedColumnName = "REF"),
    @JoinColumn(name = "B_TABLE_NAME.OTHER", referencedColumnName = "'123'")})
@OneToMany
private Set<B> bs;

Обратите внимание на одинарные кавычки в referencedColumnName, это значение, которое вы ищете.

Подробнее здесь .

...