いくつかのエンティティをネストしています。ただし、取得時に、アクティブなエンティティのみを取得する必要があります。
@Entity
public class System {
@Id
@Column(name = "ID")
private Integer id;
@OneToMany(mappedBy = "system")
private Set<Systemproperty> systempropertys;
}
@Entity
public class Systemproperty {
@Id
@Column(name = "ID")
private Integer id;
@Id
@Column(name = "ACTIVE")
private Integer active;
}
Systemproperties
をリクエストするときは、active
(active = 1)のプロパティのみを取得したいと思います。
周りを検索すると、いくつかの hibernateアノテーション と サブクエリ を使用する可能性が見つかりました。しかし、どちらも私には実際には機能しません。現在Hibernateを使用していますが、現在は積極的な読み込みを使用する必要があり、パフォーマンスの問題が発生する可能性があるため、Eclipselinkに置き換えることを検討しています。いくつかのレベルをネストしているため、サブクエリは実際にはうまく機能しません。
Eclipselinkには @ Customizer アノテーションが機能しているようですが、休止状態とは異なる概念に従っているようです@FilterDef
注釈であり、切り替え時に追加のオーバーヘッドが発生します。
@JoinColumn
それ以上のフィルタリングは許可されていないようです。この問題を解決するための標準的なJPAの方法はありますか?
AFAIKには、これを行うためのポータブルJPAベースの方法はありません。クリーンですが、少し非効率的な解決策は、Java側ですべてを実行し、マップされたsystempropertys
を手動で繰り返し、アクティブなプロパティの不変のセットを返すゲッターgetActiveSystemproperties()
を作成することです。
@ 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;
}
JPAの方法はありませんが、Hibernate filetrsを試すことができます: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-filters
EclipseLinkで同様の問題を解決する必要がありました。特別なSessionCustomizerを使用し、OneToManyアノテーションのマッピング条件を変更しました。 MaybeeHibernateにも似たようなものがあります。
カスタマイザを永続性ユニットに追加します。
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);
}
}
}
}
}
}