Аннотация для фильтрации результатов ассоциации @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).
Заранее благодарим за любые советы.
Ответы
Ответ 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, это значение, которое вы ищете.
Дополнительная информация здесь.