Подтвердить что ты не робот

Аннотация для фильтрации результатов ассоциации @OneToMany

У меня есть родительское/дочернее отношение между двумя таблицами и соответствующее сопоставление в моих классах 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

Дополнительным фильтром будет только имя столбца и жестко закодированное значение. Есть ли способ сделать это с помощью аннотаций спящего режима?

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

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

4b9b3361

Ответ 1

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

Hibernate Core Reference Documentation

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

Пример

@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

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

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

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

Ответ 3

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

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

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

Дополнительная информация здесь.