gpt4 book ai didi

java - Eclipselink:使用定制器添加Where-子句

转载 作者:太空宇宙 更新时间:2023-11-04 11:03:38 25 4
gpt4 key购买 nike

在我当前的项目中,我们将重构对数据库实体的 nls 支持。在我们之前的版本中,我们使用了 session 语言,但不幸的是这种行为并不完全稳定。因此我们将更改代码,以便将语言信息存储在查询内部。我希望有一个中央实例来处理这种语言行为,而不是在整个项目中的每个实体中更改每个查询。

例如我有这个实体:

@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 的每个调用。

更有利的方法是使用定制器来添加区域设置参数。 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 block 内设置此参数?

我正在使用 Eclipselink 2.5,非常感谢任何帮助

最佳答案

如果您不介意使用特定于供应商的解决方案,您可以使用 EclipseLink @AdditionalCriteria 注释。您可以按如下方式使用它:

  • 创建一个抽象映射类并从中派生所有实体:

    @MappedSuperclass
    @AdditionalCriteria("this.language = :lang")
    public class AbstractEntity {

    private String language;

    // getters + setters
    }
  • 让您的实体对其进行子类化:

    public class NLSBackendEntity extends AbstractEntity implements Serializable {
    // ...
    }
  • 在实体管理器或实体管理器工厂上设置语言属性的值:

    entityManager.setProperty("language", "de"); 

在执行查询之前。 EclipseLink 应将 language = ? 附加到绑定(bind)您在实体管理器上设置的值的查询的 where 条件。

关于java - Eclipselink:使用定制器添加Where-子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46642000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com