我遇到了hibernate的问题。我最近将我的hbm2ddl设置为validate,并且它一直在抱怨错误的数据类型。除了布尔值,我已解决了所有问题。
我的班级中有一个字段opener
,其映射为:
<property column="opener" name="opener" type="boolean"/>
列opener
是tinyint (4)
,其值为1或0.到目前为止,我已尝试更改类型,但无济于事。我也尝试在hibernate.cfg中使用以下设置:
<property name="hibernate.query.substitutions">true 1, false 0</property>
但我仍然遇到同样的错误。我做错了什么?
org.hibernate.HibernateException: Wrong column type: opener, expected: bit
at org.hibernate.mapping.Table.validateColumns(Table.java:261)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1083)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:317)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
注意:我无法访问数据库。
答案 0 :(得分:4)
如果您无法在表格中更改SQL类型,我建议您这样做:
<property name="opener" column="opener" type="path.to.your.package.YourClassUserType"/>
创建你的课程:
import org.hibernate.usertype.UserType;
public class YourClassUserType implements UserType{
...
}
您必须从UserType接口实现方法。 实现将字节转换为布尔值(因为TINYINT在Java中以字节映射)
祝你好运:)答案 1 :(得分:4)
对于遇到与我同样麻烦的人,我在这里使用了两个答案的组合。
我实现了一个自定义的usertype来处理我的tinyint字段:
public class TinyIntegerToBoolean implements UserType {
public int[] sqlTypes() {
return new int[]{Types.TINYINT};
}
public Class returnedClass() {
return Boolean.class;
}
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor si, Object owner) throws HibernateException, SQLException {
return (rs.getByte(names[0]) != 0);
}
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor si) throws HibernateException, SQLException {
st.setByte(index, Boolean.TRUE.equals(value) ? (byte) 1 : (byte) 0);
}
/* boilerplate... */
public boolean isMutable() {
return false;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == null || y == null) {
return false;
} else {
return x.equals(y);
}
}
public int hashCode(Object x) throws HibernateException {
assert (x != null);
return x.hashCode();
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
}
然后我将以下内容添加到我的映射中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<typedef class="com.test.model.TinyIntegerToBoolean" name="tinyint_boolean"/>
</hibernate-mapping>
然后在我的开场白字段中,我使用type=tinyint_boolean
,它就像一个魅力:)
答案 2 :(得分:3)
您可以将数据库列定义为char(1)
,并在Hibernate映射文件中将属性定义为type="yes_no"
,这是一种Java布尔类型。这些将在数据库中显示为Y
和N
值。
如果你想使用tiny_int
,那么大小必须是1,但我不能100%确定它在HBM文件中的映射方式。
答案 3 :(得分:1)
试试这个:
<property column="opener" name="opener" access="field" />
假设你有一个吸气剂
boolean isOpener() ;
和一个二传手
void setOpener(boolean b);
答案 4 :(得分:0)
您可以尝试将numeric_boolean
用作类型:
<property column="opener" name="opener" type="numeric_boolean"/>
答案 5 :(得分:0)
这是一个棘手的问题,因为您无权访问数据库。但是可以通过一些工作来完成
您需要做的是创建自定义类型类。该类基本上将从数据库(1或0)中检索值,并且它将包含返回true或false Boolean对象的逻辑。
以下是一个例子:
http://alenovarini.wikidot.com/mapping-a-custom-type-in-hibernate
您的新类型的映射将如下所示:
<typedef class="com.path.to.my.package.CustomBooleanType" name="myBoolType" />
该类nullSafeGet方法将返回包含true或false的Boolean对象。
所以你的新映射将包含:
<property column="opener" name="opener" type="myBoolType"/>