使用 hibernate 映射布尔值

发布于 2024-11-10 16:01:16 字数 1085 浏览 2 评论 0原文

我在休眠方面遇到了麻烦。我最近将 hbm2ddl 设置为验证,它一直抱怨错误的数据类型。我已经解决了除布尔值之外的所有问题。

我的类中有一个字段 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)

注意:我无权访问数据库。

I'm running into trouble with hibernate. I recently set my hbm2ddl to validate, and it has been complaining a lot about wrong datatypes. I have fixed every problem except for booleans.

I have a field opener in my class, which is mapped as:

<property column="opener" name="opener" type="boolean"/>

The column opener is a tinyint (4) and has a value of 1 or 0. So far I've tried changing the types, but to no avail. I have also tried using the following setting in my hibernate.cfg:

<property name="hibernate.query.substitutions">true 1, false 0</property>

But I am still getting the same error. What am I doing wrong?

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)

note: I have no access to the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

国粹 2024-11-17 16:01:16

如果您无法更改表中的 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 中以字节映射)

请参阅 示例

祝你好运:)

If you can't change your SQL type in your table, i recommend you to do this :

<property name="opener" column="opener" type="path.to.your.package.YourClassUserType"/>

and create your class :

import org.hibernate.usertype.UserType;

public class YourClassUserType implements UserType{
 ...
}

you have to implement methods from the interface UserType.
The implementation will transform byte to boolean (because a TINYINT is mapped in byte in Java)

see examples here

good luck :)

一瞬间的火花 2024-11-17 16:01:16

对于遇到与我同样麻烦的人,我使用了此处发布的两个答案的组合。

我实现了一个自定义用户类型来处理我的 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>

然后在我的 opener 字段中我使用 type=tinyint_boolean ,它的工作方式就像一个魅力:)

For anyone who ran into the same trouble as me, I used a combination of two answers posted here.

I implemented a custom usertype to handle my tinyint field:

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;
    }
}

Then I added the following to my mappings:

<?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>

Then in my opener field I use type=tinyint_boolean and it works like a charm :)

写下不归期 2024-11-17 16:01:16

您可以将 DB 列定义为 char(1),并在 Hibernate 映射文件中将属性定义为 type="yes_no",它是 Java 布尔类型。这些将在数据库中显示为 YN 值。

如果您想使用 tiny_int ,那么大小必须为 1,但我不能 100% 确定它是如何映射到 HBM 文件中的。

You can define your DB column as a char(1) and in your Hibernate mapping file define the property as type="yes_no", which is a Java Boolean type. These will appear as Y and N values in the DB.

If you want to use tiny_int then the size will have to be 1, but I'm not 100% sure how this is mapped in the HBM file.

油焖大侠 2024-11-17 16:01:16

试试这个:

<property column="opener" name="opener" access="field" />

假设你有一个 getter

 boolean isOpener() ;

和一个 setter

void setOpener(boolean b);

try this :

<property column="opener" name="opener" access="field" />

assuming that you got a getter

 boolean isOpener() ;

and a setter

void setOpener(boolean b);
硬不硬你别怂 2024-11-17 16:01:16

您可以尝试使用 numeric_boolean 作为类型:

<property column="opener" name="opener" type="numeric_boolean"/>

You can try to use numeric_boolean as a type:

<property column="opener" name="opener" type="numeric_boolean"/>
羅雙樹 2024-11-17 16:01:16

这是一个棘手的问题,因为您无权访问数据库。但这可以通过一些工作来完成,

您需要做的是创建一个自定义类型类。此类基本上将从数据库中检索值(1 或 0),并将包含返回 true 或 false 布尔对象的逻辑。

这是一个示例:

http://alenovarini.wikidot.com/mapping- a-custom-type-in​​-hibernate

新类型的映射将如下所示:

    <typedef class="com.path.to.my.package.CustomBooleanType" name="myBoolType" />

该类 nullSafeGet 方法将返回包含 true 或 false 的布尔对象。

所以你的新映射将包含:

<property column="opener" name="opener" type="myBoolType"/>

This is a tricky one because you have no access to the database. But it can be done with a bit of work

What you will need to do is create a custom type class. This class will basically retrieve the value from the database (1 or 0) and it will contain logic that returns either a true or false Boolean object.

Here is an example:

http://alenovarini.wikidot.com/mapping-a-custom-type-in-hibernate

your mapping for your new type will look like:

    <typedef class="com.path.to.my.package.CustomBooleanType" name="myBoolType" />

That classes nullSafeGet method will return your Boolean object that will contain true or false.

so your new mapping will contain:

<property column="opener" name="opener" type="myBoolType"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文