我有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)
但我面临同样的问题。 我做错了什么事。请帮帮我。
答案 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>
因此,您必须确保所有查询参数都填充空格。