Hibernate HQL查询中的Oracle char类型问题

时间:2014-05-16 16:06:33

标签: oracle hibernate types char hql

我有Oracle表,其中包含char类型列。在我的Entity类中,我将oracle char类型映射到java字符串类型。

以下是我的Entity类的代码。

@Entity
@Table(name="ORG")
public class Organization  {

private String serviceName;
private String orgAcct;

     //Some other properties goes here...

@Column(name="ORG_ACCT", nullable=false, length=16)
public String getOrgAcct() {
    return this.orgAcct;
}

public void setOrgAcct(String orgAcct) {
    this.orgAcct = orgAcct;
}


@Column(name="SERVICE_NAME",nullable=true, length=16)
public String getServiceName() {
    return this.serviceName;
}

public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
}

}

这里serviceName和orgAcct都是Oracle中的char类型变量

在我的DAO类中,我使用serviceName和orgAcct属性编写了一个HQL查询来获取Oranization实体对象。

@Repository
@Scope("singleton") //By default scope is singleton
public class OrganizationDAOImpl implementsOrganizationDAO {

public OrganizationDAOImpl(){
}

public Organization findOrganizationByOrgAcctAndServiceName(String orgAcct,String serviceName){
    String hqlQuery = "SELECT org FROM  Organization org WHERE org.serviceName = :serName AND org.orgAcct = :orgAct";
    Query query = getCurrentSession().createQuery(hqlQuery)
        .setString("serName", serviceName)
        .setString("orgAct", orgAcct);

    Organization org =  findObject(query);
    return org;
}
 }

但是当我调用findOrganizationByOrgAcctAndServiceName()方法时,我将组织对象变为空(即HQL查询不检索Char类型数据)。

请帮我解决这个问题。在这里,我无法将Oracle类型char更改为Varchar2。我需要使用oracle char类型变量。

@EngineerDollery在上面的帖子之后,我使用columnDefinition,@Column注释属性修改了我的Entity类。

@Column(name="SERVICE_NAME",nullable=true,length=16,columnDefinition="CHAR")
    public String getServiceName() {
        return this.serviceName;
    }

但我仍然无法检索相应列的数据。

我在columnDefinition属性中添加了列大小。

@Column(name="SERVICE_NAME",nullable=true,length=16,columnDefinition="CHAR(16)

但我面临同样的问题。 我做错了什么事。请帮帮我。

2 个答案:

答案 0 :(得分:1)

我使用OraclePreparedStatement和Hibernate UserType接口解决了这个问题。

通过扩展org.hibernate.usertype.UserType接口并为nullSafeSet(),nullSafeGet()方法提供实现来创建一个新的UserType类。

nullSafeSet()方法,我们有第一个参数作为PreparedStatement,在我将PreparedStatement转换为OraclePreparedStatement对象的方法中,并使用setFixedCHAR()方法传递String值。

以下是UserType impl类的完整代码。

package nc3.jws.persistence.userType;

import java.io.Serializable;
import java.sql.PreparedStatement; 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.apache.commons.lang.StringUtils;
import org.hibernate.type.StringType;
import org.hibernate.usertype.UserType;

/**
* 
* based on www.hibernate.org/388.html
*/

 public class OracleFixedLengthCharType implements UserType {

public OracleFixedLengthCharType() {
    System.out.println("OracleFixedLengthCharType constructor");
}

public int[] sqlTypes() {
    return new int[] { Types.CHAR };
}



public Class<String> returnedClass() {
    return String.class;
}

public boolean equals(Object x, Object y) {
    return (x == y) || (x != null && y != null && (x.equals(y)));
}

@SuppressWarnings("deprecation")
public Object nullSafeGet(ResultSet inResultSet, String[] names, Object o) throws SQLException {
    //String val = (String) Hibernate.STRING.nullSafeGet(inResultSet, names[0]);
    String val = StringType.INSTANCE.nullSafeGet(inResultSet, names[0]);
    //System.out.println("From nullSafeGet method valu is "+val);
    return val == null ? null : StringUtils.trim(val);
}


public void nullSafeSet(PreparedStatement inPreparedStatement, Object o,
        int i)
                throws SQLException {

    String val = (String) o;
    //Get the delegatingStmt object from DBCP connection pool PreparedStatement object.
    org.apache.commons.dbcp.DelegatingStatement delgatingStmt = (org.apache.commons.dbcp.DelegatingStatement)inPreparedStatement;
    //Get OraclePreparedStatement object using deletatingStatement object.

    oracle.jdbc.driver.OraclePreparedStatement oraclePreparedStmpt = (oracle.jdbc.driver.OraclePreparedStatement)delgatingStmt.getInnermostDelegate();
    //Call setFixedCHAR method, by passing string type value .
    oraclePreparedStmpt.setFixedCHAR(i, val);
}


public Object deepCopy(Object o) {
    if (o == null) {
        return null;
    }
    return new String(((String) o));
}


public boolean isMutable() {
    return false;
}

public Object assemble(Serializable cached, Object owner) {
    return cached;
}


public Serializable disassemble(Object value) {
    return (Serializable) value;
}

public Object replace(Object original, Object target, Object owner) {
    return original;
}

public int hashCode(Object obj) {
    return obj.hashCode();
}

  }

在Entity类中使用@TypeDefs注释配置此类。

@TypeDefs({
@TypeDef(name = "fixedLengthChar", typeClass = nc3.jws.persistence.userType.OracleFixedLengthCharType.class)

})

将此类型添加到CHAR类型列

@Type(type="fixedLengthChar")
@Column(name="SERVICE_NAME",nullable=true,length=16)
public String getServiceName() {
    return this.serviceName;
}

答案 1 :(得分:0)

char类型在表中填充空格。这意味着如果你有

foo

在其中一列中,您实际拥有的是

foo<space><space><space>...

直到字符串的实际长度为16。

因此,如果您正在寻找一个以"foo"作为其服务名称的组织,您将找不到任何组织,因为如果foo填充了13个空格,表格中的实际值。< / p>

因此,您必须确保所有查询参数都填充空格。