Eclipselink NamedNativeQuery 将列名作为参数而不是值传递

Posted

技术标签:

【中文标题】Eclipselink NamedNativeQuery 将列名作为参数而不是值传递【英文标题】:Eclipselink NamedNativeQuery pass column name as parameter and not a value 【发布时间】:2019-03-27 13:50:48 【问题描述】:

试图将列名作为参数传递,但 JPA 将其设置为用单引号括起来的值。

@NamedNativeQueries(
    @NamedNativeQuery(
            name = "Genre.findAllLocalized",
            query = "SELECT "
                    + " CASE "
                    + "     WHEN ? IS NULL THEN genre_default"
                    + "     ELSE ? "
                    + " END localized_genre "
                    + "FROM genre ORDER BY localized_genre")
)

然后:

List<String> res = em.createNamedQuery("Genre.findAllLocalized")
                .setParameter(1, colName)
                .setParameter(2, colName)
                .getResultList();

问题是被传递的列名被视为,因此结果将返回具有重复值"col_name"的结果列表,而不是选择作为参数传递的列的值。

这可以实现吗?

【问题讨论】:

【参考方案1】:

基本上,像这样创建一个准备好的查询是没有意义的,无论如何你会如何命名该查询:“*”?所以简短的回答是:不。

    但如果这符合您的要求,您可以动态创建命名查询:

    String colName = "colName";
    String query = "SELECT WHEN " + colName + " IS NULL THEN genre_default";
    Query query = entitymanager.createQuery(query);
    

    可能使用标准构建器更符合您想要使用 JPA 的方式(代码来自 https://en.wikibooks.org/wiki/Java_Persistence/Criteria):

    // Select the employees and the mailing addresses that have the same address.
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
    Root employee = criteriaQuery.from(Employee.class);
    Root address = criteriaQuery.from(MailingAddress.class);
    criteriaQuery.multiselect(employee, address);
    
    criteriaQuery.where( criteriaBuilder.equal(employee.get("address"), address.get("address"));
    Query query = entityManager.createQuery(criteriaQuery);
    List<Object[]> result = query.getResultList();
    

【讨论】:

这是个坏主意,因为您打开了 SQL 注入的可能性 @H4F: 1. 如果您让用户选择创建查询,那么您的架构在大多数情况下都是值得怀疑的。 2. 用第二种方式注入是完全不可能的。

以上是关于Eclipselink NamedNativeQuery 将列名作为参数而不是值传递的主要内容,如果未能解决你的问题,请参考以下文章

Eclipselink 2.5 使用 Maven 生成元模型

EclipseLink 错误?简单的原生 SQL 查询异常

Eclipselink 实体类自动扫描发现非实体

Eclipselink 实体持续存在问题

eclipselink 连接池

eclipselink.weaving 属性的值和区别是啥?