查询数据库时出现org.hibernate.TypeMismatchException

时间:2012-07-21 20:20:15

标签: hibernate jsf

我正在开发第一个webapp,我将使用hibernate。

我有:

  • Hibernate 3.2.5
  • JSF 2.1
  • Netbeans 7.2 Rc1

我想要做的是,在我的webapp中有一个表单,用户将输入他们的凭据,然后我会将它们与我在数据库中的内容相匹配。

第一步是通过JSF获取信息==>工作良好。 下一步是查询数据库以检查我有这个用户并且密码是否正确。

对于第二步,我遇到了问题。

这是我正在调用的代码:

public String checkUser() {
    /** 1° Query the database for active users with specified name. */
    session = helper.getSessionFactory().openSession();
    PAC_USERS queryUsr = new PAC_USERS();
    session.load(PAC_USERS.class, queryUsr);
    session.beginTransaction();
    queryUsr.setName(this.name);
    this.user = (PAC_USERS) session.get(PAC_USERS.class, queryUsr);
    session.close();
    return null;
    /** 2° verify password against the one stored in the DB. */
}

这是hibernate映射文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class catalog="pac" name="com.a3c.pac.jsf.beans.PAC_USERS" table="pac_users">
       <id column="id" name="id" type="integer">
           <generator class="identity"/>
       </id>
       <property column="name" name="name" type="string"/>
       <property column="password" name="password" type="string"/>
   </class>
</hibernate-mapping>

这是我的表的SQL语句:

CREATE TABLE `pac_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  `active` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1$$

我想要的是在PAC_USERS表中查询通过网页提供名称的记录。

PAC_USERS.java类也可以提供帮助,这里是:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.a3c.pac.jsf.beans;

import java.io.Serializable;

/**
 *
 * @author Utilisateurs
 */
public class PAC_USERS implements Serializable {
    private Integer id;
    private String name;
    private String password;
    private Boolean active = false;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Boolean getActive() {
        return active;
    }

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

非常感谢任何建议。

先谢谢。

保重, 马可。

1 个答案:

答案 0 :(得分:2)

完全没有理解session.load和session.get的目的。如果你想按名称加载PAC_USERS对象(我甚至不会进入那个命名)那么你就是这样做(假设名称是唯一的):

session = helper.getSessionFactory().openSession();
this.user = (PAC_USERS) session.createQuery( "select u from PAC_USERS u where u.name = :username" )
        .setParameter( "username", this.name )
        .uniqueResult();
session.close();

但是,这里有很多事情可以做得更好。首先,这似乎是我们称之为每次操作会话的反模式的主要示例,特别是为数据库的每个请求打开和关闭会话。也许它只是这个特定用例的本质,请注意......

接下来,这是@NaturalId(或<natural-id/>)映射的一个很好的候选者。从4.1开始,Hibernate通过natural-id提供加载实体作为头等公民,与id加载相同。假设您已将名称映射为自然ID,您可以改为:

session = helper.getSessionFactory().openSession();
this.user = (PAC_USERS) session.bySimpleNaturalId( PAC_USERS.class ).load( this.name );
session.close();

最后,如果您对此返回用户所做的只是验证其身份验证凭据,那么最好不要返回实体。或者,直接选择密码并验证:

session = helper.getSessionFactory().openSession();
final String password = (String) session.createQuery( "select u.password from PAC_USERS where u.name = :username" )
        .setParameter( "username", this.name )
        .uniqueResult();
session.close();

或者只是在查询中执行验证:

session = helper.getSessionFactory().openSession();
final Long matches = (Long) session.createQuery( "select count(*) from PAC_USERS where u.name = :username and u.password = :pswd" )
        .setParameter( "username", this.name )
        .setParameter( "pswd", this.password )
        .uniqueResult();
// count should == 1...
session.close();