在Hibernate SQL查询中,你如何逃避?字段名称中的字符

时间:2014-06-14 14:18:40

标签: sql sql-server hibernate escaping illegal-characters

这是一个SQL Server数据库,许多年前开发人员为布尔值创建了一个包含?字符的列名。许多系统访问此数据库,因此更改此列名称对我来说不是一个选项。

这适用于原生MS工具:

SELECT * FROM MyDatabase.dbo.[My Table] WHERE [Active?]= true

同一个查询在session.createSQLQuery中失败,Hibernate在尝试将括号字段名称中的?解释为参数时抛出错误。

我尝试过反叛[Active?\]

我尝试用/逃避! [Active /!?]反之亦然!/ [Active!/?]无效。

我还查看过相当多的堆栈溢出和网络论坛以获取其他建议,但我尝试过的其他事情都没有奏效。

这是hibernate中的错误吗?在我看来,括号中的任何内容都不应该被解释为参数。

特定错误是查询异常

> Expected positional parameter count: 1, actual parameters:[]

附加了查询字符串。

joachim-isaksson已回答:[Active\\?]

2 个答案:

答案 0 :(得分:4)

要复制此用例,我在SQLServerEscapeQuestionCharacterTest中创建了high-performance-java-persistence GitHub repository

假设您具有以下JPA实体:

@Entity(name = "Post")
@Table(name = "[post]")
public static class Post {

    @Id
    private Long id;

    private String title;

    @Column(name = "[active?]")
    private boolean active;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}

哪个与以下数据库表相关联:

CREATE TABLE [post] (
    id bigint not null, 
    [active?] bit, 
    title varchar(255), 
    PRIMARY KEY (id)
)

如果您创建以下Post实体:

Post post = new Post();
post.setId(1L);
post.setTitle("High-Performance Java Persistence");
post.setActive(true);

entityManager.persist(post);

Hibernate将执行正确的INSERT语句:

INSERT INTO [post] (
    [active?], 
    title, 
    id
) 
VALUES (
    true, 
    'High-Performance Java Persistence', 
    1
)

执行JPQL查询时:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "where p.active = :active", Post.class)
.setParameter("active", true)
.getResultList();

assertEquals(1, posts.size());

Hibernate使用JPA name的{​​{1}}属性,该属性已经转义了列名:

@Column

对于本机SQL查询,您需要像这样转义SELECT p.id AS id1_0_, p.[active?] AS active2_0_, p.title AS title3_0_ FROM [post] p WHERE p.[active?] = true 字符:

?

而且,它就像一种魅力。

答案 1 :(得分:-2)

@ joachim-isaksson已回答togglebutton1_click(object sender, EventhandlerArgs e){ value += 1; taskPane.label.text = "" + value; }