在我當前的項目中,我們將折射器對數據庫實體的nls支持。在我們以前的版本中,我們使用會話語言,但不幸的是,這種行爲並不完全穩定。所以我們將更改代碼,以便語言信息存儲在查詢中。 我很想有一箇中央實例來處理這種語言行爲,而不是改變每個查詢,在每個實體遍佈整個項目。Eclipselink:使用定製器添加子句子
E.g.我有這樣的實體:
@NamedQueries({
@NamedQuery(name = NLSBackendEntity.findAll,
query = "select n from NLSBackendEntity n"),
@NamedQuery(name = NLSBackendEntity.getById,
query = "select n from NLSBackendEntity n where n.nlsBackendKey.key = :key") })
@Entity
@Table(name = "backend_key_al")
public class NLSBackendEntity implements Serializable
{
private static final long serialVersionUID = 1L;
public static final String findAll = "NLSBackend.findAll";
public static final String getById = "NLSBackend.getById";
@EmbeddedId
private NLSBackendKey nlsBackendKey;
/**
* The text in the language.
*/
@Lob
@Column(name = "TEXT")
private String text;
NLSBackendEntity()
{
// no arg constructor needed for JPA
}
public String getKey()
{
return nlsBackendKey.key;
}
public String getLanguage()
{
return nlsBackendKey.language;
}
public String getText()
{
return text;
}
@Embeddable
public static class NLSBackendKey implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* the NLS-key.
*/
@Column(name = "KEY")
private String key;
/**
* The language of this entry.
*/
@Column(name = "LOCALE")
private String language;
}
}
一種可能性現在是添加n.nlsBackenKey.language = :locale
每NamedQuery
和更改所有調用,在這個NamedQuery
引用。
更有利的方法是讓Customizer
添加區域設置參數。 ATM我有這樣的:
public class QueryLanguageCustomizer implements DescriptorCustomizer
{
@Override
public void customize(ClassDescriptor descriptor) throws Exception
{
ExpressionBuilder eb = new ExpressionBuilder(descriptor.getJavaClass());
Expression languageExp = eb.getField("LOCALE").equal(eb.getParameter("locale"));
descriptor.getQueryManager().setAdditionalJoinExpression(languageExp);
}
}
,我已將此添加到NLSBackendEntity
:@Customizer(QueryLanguageCustomizer.class)
但現在,我不能設置此參數。再次,我常用的手段,是使用一個SessionEventAdapter
:
public class LanguageSessionEventListener extends SessionEventAdapter {
/** Log for logging. */
private static final Log LOG = LogFactory
.getLog(LanguageSessionEventListener.class);
@Override
public void preExecuteQuery(SessionEvent event) {
LOG.debug("preExecuteQuery called for session= "
+ event.getSession().getName());
event.getQuery().getTranslationRow().put("LOCALE", getLocale());
super.preExecuteQuery(event);
}
private String getLocale() {
// uninteresting for this example
}
}
不幸的是,無論我怎麼努力,我不能設置此參數。 getTransaltionRow()
返回null
,我試過的每一個可能性都失敗了。
是否不可能在preExecuteQuery
塊內設置此參數?我使用的EclipseLink 2.5
,任何幫助,高度讚賞
我也想過這個。問題是,該語言可能會在EntityManager的生命週期內發生變化。 Eclipselink的狀態[這裏](http://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_additionalcriteria.htm):「不要更改實體管理器生命週期的屬性。」 –
嗯,我也讀過。但我不知道你在使用什麼環境;如果您處於JEE環境並使用事務範圍的實體管理器,則實體管理器的生命週期是當前方法的範圍或啓動事務的方法的範圍。如果你的配置在這個範圍內發生了變化,那麼我認爲這不會對你有所幫助。 – ujulu