【问题标题】:Hibernate Criteria creates a '?' in the generated SQLHibernate Criteria 创建一个“?”在生成的 SQL
【发布时间】:2012-10-12 09:13:20
【问题描述】:

我创建了一个示例 Web 应用程序。我使用 MS SQL Server 2008 作为数据库并使用 hibernate + 注释来访问数据库。我的休眠配置xml如下。 问题是,Criteria.list() 返回一个空列表,而且我看到一个“?”在生成的 HSQL 中,而不是我在 Criteria 中传递的参数。

<session-factory name="">
    <property name="hibernate.connection.driver_class">sun.jdbc.odbc.JdbcOdbcDriver</property>
    <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
    <property name="hibernate.connection.url">jdbc:odbc:dbname</property>

    <property name="connection.pool_size">10</property>
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>       

     <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>       
    <property name="hibernate.connection.username"></property>
    <property name="hibernate.connection.password"></property>

<mapping class="com.demo.Person" />
</session-factory>

这是我的注释豆

    @Entity
    @Table(name = "person")
    public class Person implements Serializable {

        public Person(){

        }
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO) 
        @Basic(optional = false)
        @Column(name = "personid")
        private Integer personid;

        @Basic(optional = false)
        @Column(name = "firstname")
        private String firstname;

        @Column(name = "lastname")
        private String lastname;

        @Basic(optional = false)
        @Column(name = "phone")
        private String phone;

        @Column(name = "mobile")
        private String mobile;

        @Column(name = "street")
        private String street;

        @Basic(optional = false)
        @Column(name = "city")
        private String city;

        @Basic(optional = false)
        @Column(name = "country")
        private String country;

        @Basic(optional = false)
        @Column(name = "bussinessowner")
        private int bussinessowner;

        @OneToMany(cascade = CascadeType.ALL, mappedBy = "resultid1")
        private Collection<Recent> recentCollection;

//setters & getters
}

而我正在运行的代码是

Session session;
        List list = new ArrayList();
        try{
        session = HibernateUtil.getSessionFactory().openSession();
        Criteria criteria = session.createCriteria(Person.class);
        criteria.add(Restrictions.like("firstname", name, MatchMode.START));
        list= criteria.list();
        System.out.println(list.size());

        }catch (Exception e) {
            e.printStackTrace();
        }

生成的 HSQL:

Hibernate: select this_.personid as personid2_0_,  this_.city as city2_0_, this_.country as country2_0_, this_.firstname as firstname2_0_, this_.lastname as lastname2_0_ from person this_ where this_.firstname like ?

除此之外,我也没有遇到任何异常。你能帮我解决这个问题吗? 谢谢!

【问题讨论】:

  • 代码似乎没有错误。您是否检查过手动将查询写入数据库,它是否返回任何结果?
  • 是的,如果我在管理工作室执行查询,它会返回结果。但在上面的代码中,它返回的是空列表。
  • "?"用于准备好的语句 - 这里没有错误。当您手动执行查询时,您用什么替换“?”与?
  • ? 只是name 的值作为参数传递给 JDBC 驱动程序的标志(因为它应该是!)而不是直接在SQL 子句。我怀疑退货清单为空的原因是别的。
  • 好的,但是如果我在管理工作室中执行相同的查询,那么我就能得到结果。我还缺少其他东西吗?

标签: java hibernate annotations sql-server-2008-r2


【解决方案1】:

将其更改为criteria.add(Restrictions.like("firstname", name + "%")); 有帮助吗? 顺便说一下,?jbdc 语句的正确参数占位符。

【讨论】:

  • 我使用Query 尝试了同样的方法并对查询进行硬编码,这样它就可以正常工作。但是使用Criteria 并没有获取任何结果!
  • 您确定在一个数据库实例上运行这两个查询吗?也许它指向不同的数据库,这就是你可以获得不同的结果。
  • 我的系统中只有一个数据库,我确信我在同一个数据库上运行这两个查询
  • 我看到您在查询中使用了不同的字段,正如您在之前的评论中提到的那样。只需将标准中的firstname 更改为name 即可。
【解决方案2】:

'?'是 JDBC 语句中参数的占位符。你看不到它的实际价值,仅此而已。没有问题,只是使用hibernate的跟踪仍然不完整。

如果您想查看 '?' 的实际值,则必须使用额外的产品,例如 log4jdbc

【讨论】:

    【解决方案3】:

    @Rakesh 试试下面的代码:

    criteria.add(Restrictions.ilike("firstname", name +"%"));
    

    【讨论】:

      【解决方案4】:

      代替这一行

      criteria.add(Restrictions.like("firstname", name, MatchMode.START)); 
      

      试试

      criteria.add(Restrictions.like("firstname", name, MatchMode.ANYWHERE)); 
      

      criteria.add(Restrictions.ilike("firstname", name, MatchMode.ANYWHERE)); 
      

      如果您将 firstname 作为 "abcd" 传递,它将生成 SQL 作为 firstname like '%abcd%'

      你可以试试这个吗

      session = HibernateUtil.getSessionFactory().openSession(); 
      List<Person> personList = session.createQuery("Select * from Person p where p.firstname like 'rake%'").list();
      
      System.out.println("Person result :" + personList .size());
      

      【讨论】:

      • 我尝试使用 Query 并硬编码查询,这样它工作正常。但是使用 Criteria 并没有获取任何结果!
      • ANYWHERE 也返回一个空列表 :(
      • 您在数据库表中是否有该名字的记录?请分享您正在执行并返回结果的 SQL 查询
      • 我确实在该表中有记录。返回结果的 SQL 查询是:SELECT * FROM person WHERE firstname LIKE 'rake%'
      • @Rakesh 'name' 和 'firstname' 是不同的字段吗?
      猜你喜欢
      • 1970-01-01
      • 2019-04-27
      • 2012-05-25
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 2021-05-29
      相关资源
      最近更新 更多